Twitter App Only Authentication example

This example is to showcase how we can search in twitter android sdk WITHOUT LOGIN (Yes it is possible) . Twitter4j Offers this.

 

Twitter search example without login

Twitter search example without login

 

Twitter offers applications the ability to issue authenticated requests on behalf of the application itself (as opposed to on behalf of a specific user). Twitter’s implementation is based on the Client Credentials Grant flow of the OAuth 2 specification. Note that OAuth 1.0a is still required to issue requests on behalf of users.

With Application-only authentication you don’t have the context of an authenticated user and this means that any request to API for endpoints that require user context, such as posting tweets, will not work. However, the set of endpoints that will still be available can have a higher rate limit.

Your app will be able to, for example:

  • Pull user timelines;
  • Access friends and followers of any account;
  • Access lists resources;
  • Search in tweets;
  • Retrieve any user information;

And it won’t be able to:

  • Post tweets or other resources;
  • Connect in Streaming endpoints;
  • Search for users;
  • Use any geo endpoint;
  • Access DMs or account credentials;
Find the Source code of the example on github

Do In Background method of my async task

 

@Override
        protected Integer doInBackground(String... params) {
            try {
                ConfigurationBuilder builder = new ConfigurationBuilder();
                builder.setUseSSL(true);
                builder.setApplicationOnlyAuthEnabled(true);
                builder.setOAuthConsumerKey(TWIT_CONS_KEY);
                builder.setOAuthConsumerSecret(TWIT_CONS_SEC_KEY);

                OAuth2Token token = new TwitterFactory(builder.build()).getInstance().getOAuth2Token();

                builder = new ConfigurationBuilder();
                builder.setUseSSL(true);
                builder.setApplicationOnlyAuthEnabled(true);
                builder.setOAuthConsumerKey(TWIT_CONS_KEY);
                builder.setOAuthConsumerSecret(TWIT_CONS_SEC_KEY);
                builder.setOAuth2TokenType(token.getTokenType());
                builder.setOAuth2AccessToken(token.getAccessToken());

                Twitter twitter = new TwitterFactory(builder.build()).getInstance();

                Query query = new Query(params[0]);
                // YOu can set the count of maximum records here
                query.setCount(50);
                QueryResult result;
                result = twitter.search(query);
                List<twitter4j.Status> tweets = result.getTweets();
                StringBuilder str = new StringBuilder();
                if (tweets != null) {
                    this.tweets = new ArrayList<Tweet>();
                    for (twitter4j.Status tweet : tweets) {
                        str.append("@" + tweet.getUser().getScreenName() + " - " + tweet.getText() + "\n");
                        System.out.println(str);
                        this.tweets.add(new Tweet("@" + tweet.getUser().getScreenName(), tweet.getText()));
                    }
                    return SUCCESS;
                }
            } catch (Exception e) {
                e.printStackTrace();
            }

            return FAILURE;
        }

 

If you observe the above code. We are creating our own configuration using ConfigureBuilder class. You only need your consumer key and consumer secret key

After that set the

 

Create your own OAuthToken which allows application to access rest API

than setApplicationOnlyAuthEnabled flag true

Set OAuthToken parameter and after that you are good to go.


Find the Source code of the example on github.

Securely store user credentials

We always store user’s credentials like User-name/Email Id or passwords, some times API public Keys also.

Some uses database(worst option), Shared Preferences (Better) .

We knows that this can be vulnerable, as security is always a problem with rooted devices. So we think of the other options.

Someone comes and says hey lets encrypt the data (Ok Good suggestion). I will say I can still decrypt the apk file.

Also can deobfuscate your code files and understand the the algorithm used for encryption and decryption (Simple :p) .

Let me explain.

First we will write two methods for encryption and decryption.

The functions are very straight forward. I have put them in AESHelper.java wrapper class.

Which looks like below.

import java.security.SecureRandom;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;

public class AESHelper {
    public static String encrypt(String seed, String cleartext)
            throws Exception {
        byte[] rawKey = getRawKey(seed.getBytes());
        byte[] result = encrypt(rawKey, cleartext.getBytes());
        return toHex(result);
    }

    public static String decrypt(String seed, String encrypted)
            throws Exception {
        byte[] rawKey = getRawKey(seed.getBytes());
        byte[] enc = toByte(encrypted);
        byte[] result = decrypt(rawKey, enc);
        return new String(result);
    }

    private static byte[] getRawKey(byte[] seed) throws Exception {
        KeyGenerator kgen = KeyGenerator.getInstance("AES");
        SecureRandom sr = SecureRandom.getInstance("SHA1PRNG");
        sr.setSeed(seed);
        kgen.init(128, sr); // 192 and 256 bits may not be available
        SecretKey skey = kgen.generateKey();
        byte[] raw = skey.getEncoded();
        return raw;
    }

    private static byte[] encrypt(byte[] raw, byte[] clear) throws Exception {
        SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
        Cipher cipher = Cipher.getInstance("AES");
        cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
        byte[] encrypted = cipher.doFinal(clear);
        return encrypted;
    }

    private static byte[] decrypt(byte[] raw, byte[] encrypted)
            throws Exception {
        SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
        Cipher cipher = Cipher.getInstance("AES");
        cipher.init(Cipher.DECRYPT_MODE, skeySpec);
        byte[] decrypted = cipher.doFinal(encrypted);
        return decrypted;
    }

    public static String toHex(String txt) {
        return toHex(txt.getBytes());
    }

    public static String fromHex(String hex) {
        return new String(toByte(hex));
    }

    public static byte[] toByte(String hexString) {
        int len = hexString.length() / 2;
        byte[] result = new byte[len];
        for (int i = 0; i < len; i++)
            result[i] = Integer.valueOf(hexString.substring(2 * i, 2 * i + 2),
                    16).byteValue();
        return result;
    }

    public static String toHex(byte[] buf) {
        if (buf == null)
            return "";
        StringBuffer result = new StringBuffer(2 * buf.length);
        for (int i = 0; i < buf.length; i++) {
            appendHex(result, buf[i]);
        }
        return result.toString();
    }

    private final static String HEX = "0123456789ABCDEF";

    private static void appendHex(StringBuffer sb, byte b) {
        sb.append(HEX.charAt((b >> 4) & 0x0f)).append(HEX.charAt(b & 0x0f));
    }

}

And an Activity’s code may look like

public class EncryptDecrypt extends Activity {
    public static String seedValue = "I AM UNBREAKABLE";
    public static String MESSAGE = "No one can read this message without decrypting me.";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        try {
            String encryptedData = AESHelper.encrypt(seedValue, MESSAGE);
            Log.v("EncryptDecrypt", "Encoded String " + encryptedData);
            String decryptedData = AESHelper.decrypt(seedValue, encryptedData);
            Log.v("EncryptDecrypt", "Decoded String " + decryptedData);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

At this point of time, as I said it is very easy to get that public key

public static String seedValue = "I AM UNBREAKABLE";

In such circumstances I have better solution. I will use NDK the best available solution.

Using NDK and building your code creates .so file. To decompile a .so file is a herculean task.

Now Add following line of code in your Activity.

static {
        System.loadLibrary("library-name");
    }
 
public native String getSecretKey();

Your .C file will look like

Java_com_example_encryptdecrypt_EncryptDecrypt_getSecretKey( JNIEnv* env,
                                                  jobject thiz )
{
    return (*env)->NewStringUTF(env, "I AM UNBREAKABLE");
}

Now add below mentioned line in your Activity before starting your encryption process.

seedValue = getSecretKey();
And you are secure now.
Happy coding and Stay Secure.🙂

 

Android Float Label Example

FloatingLabel Allows you to create a blow kind of EditText.

Floating Lable project is in initial mode, where a few customization is provided like changing Text color of EditText and Its Label

form-animation-_gif_-1

<com.hardik.floatinglabel.FloatingLabelView 
      android:id="@+id/label1" 
      android:layout_width="fill_parent" 
      android:layout_height="wrap_content" 
      label:floatHintText="Whatever hint you want to display" 
      label:textColor="@color/blue" 
      label:textTypeface="some_custome_font.ttf"/>

You can also provide custom fonts also, condition is to put them in assets folder.

Download the example and source code from github.

Modifying App Chooser Intent

Hi Friends,

I am seeing many questions on stack overflow asking about filtering app from android app chooser (though its very old topic). So I thought to write a well describing blog on it.

Problem :  Intent.ACTION_SEND lists all application which can
handle this intent. Sometimes lot of unnecessary application is
also gets listed out and user gets confuse. In most of the
cases I found that user only wants to see Facebook,Twitter,
Gmail or message option in it.

Please find below image.

device-2013-10-29-114503

When simple Intent.ACTION_SEND chosen

As you see all application is being listed.

How to remove the unnecessary apps.

Solution : Use PackageManager.  Rather than removing the unnecessary
apps , I focus on adding necessary app (Positive thinking😉 ).

Observe the below given function

private void onShareFiltered() {
	Intent emailIntent = new Intent();
	emailIntent.setAction(Intent.ACTION_SEND);
	// Native email client doesn't currently support HTML, but it doesn't
	// hurt to try in case they fix it
	emailIntent.putExtra(Intent.EXTRA_TEXT, shareText.getText().toString());
	emailIntent.putExtra(Intent.EXTRA_SUBJECT,
			getString(R.string.intent_subject));
	emailIntent.setType("message/rfc822");
		PackageManager pm = getPackageManager();
	Intent sendIntent = new Intent(Intent.ACTION_SEND);
	sendIntent.setType("text/plain");
	Intent openInChooser = Intent.createChooser(emailIntent,
			getString(R.string.app_name)
			+ getString(R.string.share_message));
	List resInfo = pm.queryIntentActivities(sendIntent, 0);
	List intentList = new ArrayList();
	for (int i = 0; i < resInfo.size(); i++) {
		// Extract the label, append it, and repackage it in a LabeledIntent
		ResolveInfo ri = resInfo.get(i);
		String packageName = ri.activityInfo.packageName;
		if (packageName.contains("android.email")) {
			emailIntent.setPackage(packageName);
		} else if (packageName.contains("twitter")
			|| packageName.contains("facebook")) {
			Intent intent = new Intent();
			intent.setComponent(new ComponentName(packageName,
					ri.activityInfo.name));
			intent.setAction(Intent.ACTION_SEND);
			intent.setType("text/plain");
			if (packageName.contains("twitter")) {
				intent.putExtra(Intent.EXTRA_TEXT, shareText.getText()
					.toString());
			} else if (packageName.contains("facebook")) {
				// Warning: Facebook IGNORES our text. They say
				// "These fields are intended for users to express themselves. 
                                //Pre-filling these fields erodes the authenticity of the user voice."
				// One workaround is to use the Facebook SDK to post, but
				// that doesn't allow the user to choose how they want to
				// share. We can also make a custom landing page, and the
				// link
				// will show the  text from that page
				// with our link in Facebook.
				intent.putExtra(Intent.EXTRA_TEXT, shareText.getText()
						.toString());
			} else if (packageName.contains("android.gm")) {
				intent.putExtra(Intent.EXTRA_TEXT, shareText.getText()
					.toString());
				intent.putExtra(Intent.EXTRA_SUBJECT,
					getString(R.string.intent_subject));
				intent.setType("message/rfc822");
			}
			intentList.add(new LabeledIntent(intent, packageName, ri
				.loadLabel(pm), ri.icon));
			}
		}

	// convert intentList to array
	LabeledIntent[] extraIntents = intentList
		.toArray(new LabeledIntent[intentList.size()]);
	openInChooser.putExtra(Intent.EXTRA_INITIAL_INTENTS, extraIntents);
	startActivity(openInChooser);
}

After executing the above method from some button click you will have a sharing screen matching like below given screen.

When we add selected apps using PackageManager

When we add selected apps using PackageManager

You can download the source code from here.

Intent Service in Android

Today I will demonstrate how to make a queue for any task in Android using Intent Service.

IntentService is a base class of Service in android. It can handle asynchronous request on demand. We can send request through

startService(Intent) method . The service gets started automatically and handles each intent when its turn comes on worker thread.

Differences between Service and IntentService

  1. Service class uses the application’s main thread, while IntentService creates a worker thread and uses that thread to run the service.
  2. IntentService creates a queue that passes one intent at a time to onHandleIntent(). Thus, implementing a multi-thread should be made by extending Service class directly. Service class needs a manual stop using stopSelf(). Meanwhile, IntentService automatically stops itself when there is no intent in queue.
  3. IntentService implements onBind() that returns null. This means that the IntentService can not be bound by default.
  4. IntentService implements onStartCommand() that sends Intent to queue and to onHandleIntent(). In brief, there are only two things to do to use IntentService. Firstly, to implement the constructor. And secondly, to implement onHandleIntent(). For other callback methods, the super is needed to be called so that it can be tracked properly.

To create a queue of few requests we can use IntentService.

Problem : Handle X number of Intents and download Images in background.

Step 1 : Create a Service and write business logic in onHandleIntent()

public class MyQueue extends IntentService {
    String name;

    public MyQueue() {
        super("MyService");
    }

    @Override
    protected void onHandleIntent(Intent intent) {
        String img_url = intent.getStringExtra(MainActivity.KEY_URL);
        String fileName = intent.getStringExtra(MainActivity.KEY_NAME);
        try {
            URL url = new URL(img_url);
            HttpURLConnection urlConnection = (HttpURLConnection) url
                    .openConnection();
            urlConnection.setRequestMethod("GET");
            urlConnection.setDoOutput(true);
            urlConnection.connect();
            File SDCardRoot = Environment.getExternalStorageDirectory();
            File file = new File(SDCardRoot, fileName);
            FileOutputStream fileOutput = new FileOutputStream(file);
            InputStream inputStream = urlConnection.getInputStream();
            byte[] buffer = new byte[1024];
            int bufferLength = 0;
            while ((bufferLength = inputStream.read(buffer)) > 0) {
                fileOutput.write(buffer, 0, bufferLength);
            }
            fileOutput.close();
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

Step 2 : Declare Service and necessary permission in AndroidManifest.xml file

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

Step 3: Start Service

public final String IMAGE_URL_1 = "http://t2.gstatic.com/images?q=tbn:ANd9GcSL0o05J2kX0aNGBTrHUiOOOJ7Js7vehTd2KTelY9PVP1JJXaiZ_A";
    public final String IMAGE_URL_2 = "http://www.hdwallpapersbest.com/wp-content/uploads/2012/12/android-wallpaper.jpg";
    public final String IMAGE_URL_3 = "http://t2.gstatic.com/images?q=tbn:ANd9GcR-ku_J_IfvDGT9Ck6OUFZyJgocRihcRWiBMKBGR6WS79i4Wbfy";

    public static final String KEY_URL = "image_url";
    public static final String KEY_NAME = "file_name";

    public static final String file_1 = "file_1.jpg";
    public static final String file_2 = "file_2.jpg";
    public static final String file_3 = "file_3.jpg";

       Intent intent = new Intent(this, MyQueue.class);
        intent.putExtra(KEY_URL, IMAGE_URL_1);
        intent.putExtra(KEY_NAME, file_1);
        startService(intent);

        intent = new Intent(this, MyQueue.class);
        intent.putExtra(KEY_URL, IMAGE_URL_2);
        intent.putExtra(KEY_NAME, file_2);
        startService(intent);

        intent = new Intent(this, MyQueue.class);
        intent.putExtra(KEY_URL, IMAGE_URL_3);
        intent.putExtra(KEY_NAME, file_3);
        startService(intent);

I have also attached source code for the same example. You can download it from here and understand it in well manner.