Saturday, 30 April 2016

Android BroadcastReceiver and PendingIntent Example

Hello Guys!!! Wishing you all Doing Well !!!!
Definition
A BroadcastReceiver is an Android app component that responds to system-wide broadcast announcements. 

Explanation
Device  screen on  or  off,  Battery is getting Low or Battery start charging, Camera captured some image all this event get  broadcast by Android System.  Apart from these system broadcast, App can also broadcast there event  like SMS app broadcasting that an SMS has being received and let other apps know about this event so that they can trigger some action.
Unlike Activities broadcast receivers do not have any user interface but may create a status bar notification. It is intended to do minimal amount of work and can delegate hardcore jobs to Services.
So you can say broadcast receivers are like hidden app components that can register for various system or application events (intents). Once any of those events occur the system notifies all the registered broadcast receivers and brings them up into action which could be notifying the user or perform some other job.

Implementation
A receiver can be registered via the AndroidManifest.xml file.
Alternatively to this static registration, you can also register a receiver dynamically via the Context.registerReceiver() method.
The implementing class for a receiver extends the BroadcastReceiver class.
If the event for which the broadcast receiver has registered happens, theonReceive() method of the receiver is called by the Android system.

Type of Broadcast

  •  Global  Broadcast
  •  Local Broadcast

Local Broadcast  :-  If you don't need to send broadcasts across applications, consider using this class with LocalBroadcastManager. This will give us a much more efficient implementation (no cross-process communication needed) and allow us to avoid thinking about any security issues related to other applications being able to receive or send your broadcasts. simple example of how to use it.
// Generally in your onResume()
LocalBroadcastManager.getInstance(this).registerReceiver(new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        String message = intent.getStringExtra("foo");
        Log.d("LocalBroadcastManager", "foo : " + message);
    }
}, new IntentFilter("my-custom-event"));

We saw how to register, now here’s how to send an intent to it:

// Send

Intent intent = new Intent("my-custom-event");

intent.putExtra("foo", "bar");

LocalBroadcastManager.getInstance(this).sendBroadcast(intent);


Global Broadcast  :-   Global Broadcast sent across the application( when cross-process communication needed).  Any application can receive(based on permission any if you provided, only intended app receive it)it.  

Type of Global Broadcast :-

  • Normal Broadcasts
  • Ordered Broadcasts

Normal Broadcast :-  It is sent with Context.sendBroadcast(). It is  completely asynchronous, i.e., the broadcasts events/intents are received by all the receivers in an asynchronous fashion. The receivers are run in an undefined order, often at the same time. It’s efficient but receivers cannot use results from other receivers or abort the entire chain of execution at a certain level.
Ordered Broadcast :-  It is sent with Context.sendOrderedBroadcast(). It is  delivered to one receiver at a time. The order can be controlled withandroid:priority attribute of the matching intent-filter. Receivers with same priority will be executed in a random order. As each receiver executes in order, it can transmit the result to the next one or even abort the entire broadcast chain so that no other receivers receive the broadcast intent and are executed.

Creating a BroadcastReceiver
Let’s quickly see how to implement a broadcast receiver

public class MyReceiver extends BroadcastReceiver {
    public MyReceiver() {
    }
    @Override
    public void onReceive(Context context, Intent intent) {
        // This method is called when this BroadcastReceiver receives an Intent broadcast.
        Toast.makeText(context, "Action: " + intent.getAction(), Toast.LENGTH_SHORT).show();
    }
}

Registering the Broadcast Receiver
We’re done with the creation but it needs to be registered so that it can receive events (intents). There are two ways to do this:

  • Statically in the manifest file.
  • Dynamically in the code.

Registering BroadcastReceiver in the Manifest File
<receiver android:name="com.example.androidtest.MyReceiver"android:enabled="true" android:exported="true" >
    <intent-filter>
        <action android:name="com.example.androidtest.BroadcastReceiver" />
    </intent-filter>
</receiver>
We use the <receiver> tag to register our broadcast receiver with an intent filter.Basically using intent filters we tell the system any intent that matches our criterias (subelements) should get delivered to that specific app component (a broadcast receiver in this case).

Registering BroadcastReceiver Programatically(Dynamically in the code)
IntentFilter filter = new IntentFilter("com.example.androidtest.BroadcastReceiver");
MyReceiver myReceiver = new MyReceiver();
registerReceiver(myReceiver, filter);

First we created an IntentFilter object that specifies which event/intent our receiver will listen to. In this case it’s com.example.androidtest.BroadcastReceiver which is a custom action name, could be anything but generally the java package naming convention is followed. We’ll use this action name again while sending a broadcast that will be handled by this receiver.

Then we instantiate our broadcast receiver and call Context.registerReceiver() to actually register our receiver that will be called and run in the main application thread.

It’s important to note that when we register a receiver in this way, it lives for as long as the component that does the registration lives. Once the component that had made the registerReceiver() call is destroyed sendBroadcast() will also stop working, hence the receiver won’t receive anymore be it an event generated from an app or the system. Whereas with the previous method where we registered via the manifest file, this is not the case. When registering a receiver in Activity.onResume(), it is strongly suggested to unregister them receivers in Activity.onPause() to avoid unnecessary system overhead as intents won’t be received when paused anyway.

@Overrideprotected void onPause() {
    unregisterReceiver(mReceiver);
    super.onPause();
}

Creating and Sending the Broadcast Event/Intent

We’ve seen how to create a broadcast receiver and then register it statically or dynamically. Finally we need to learn how to create a broadcast intent and send it to our receiver.

Intent intent = new Intent();

intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
intent.setAction("com.example.androidtest.BroadcastReceiver");
intent.putExtra("Foo", "Bar");
sendBroadcast(intent);


Second line where I setFLAG_INCLUDE_STOPPED_PACKAGES – that’s interesting. This flag basically means include intent
filters of stopped applications too in the list of potential targets to resolve
against. Similarly there isFLAG_EXCLUDE_STOPPED_PACKAGES that does the opposite, i.e., excluding. When neither or both of
them are specified then the default behaviour is including but in case of
broadcast receivers the system addsFLAG_EXCLUDE_STOPPED_PACKAGES to all broadcast intents by default. More on this subject here.
STOPPED STATE of an app is when it is
installed but not launched or force stopped from the application manager tool.
More on this here.

Pending Intents
PendingIntent is sort of an intent whose execution can be delayed and not executed right away using something like startActivity() or startActivityForResult(), but in the future. It’s an object which acts as a wrapper around an Intent object and passed on to another app. This way we can grant permission to the foreign application to execute the underlying Intent as if it were executed from our very own app’s process.
When an Intent is given to a foreign app that ships with Android or is a third party app, then they execute it with their own permissions. Whereas a PendingIntent can wrap that Intent which the foreign app executes with your own app’s permission.
Let’s see an example where we’ll create a PendingIntent and pass it on to an AlarmManager using which we’ll access the system’s alarm services that’ll allow us to schedule a piece of code to be run at some point in the future (in our case after 3 seconds).

// In the MainActivity.onCreate()
 int seconds = 3;
// Create an intent that will be wrapped in PendingIntent
Intent intent = new Intent(this, MyReceiver.class);
 // Create the pending intent and wrap our intent
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 1, intent, 0);
 // Get the alarm manager service and schedule it to go off after 3s
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
alarmManager.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + (seconds * 1000), pendingIntent);

Toast.makeText(this, "Alarm set in " + seconds + " seconds", Toast.LENGTH_LONG).show();




Friday, 5 December 2014

Twitter Integration in Android and Its new API v1.1

Twitter API v1 Retirement and Use case of Use API v1.1

The Twitter REST API v1 will officially retire on June 11, 2013 . So it is time now to migrate your all application from API v1 to API v1.1.

If you are using Twitter4J jar file in your application then simply update your application with this jar file “ twitter4j-core-3.0.3” in your libs folder of application. There is some change in method also in this file. Here I am showing the list of that method changed in this new jar file.

Retired method
migrate to
disableNotification()
updateFriendship()
enableNotification()
updateFriendship()
getProfileImage()
User#getBigger|Mini|OriginalProfileImageURL()
getBlockingUsersIDs()
getBlocksIDs()
getLocationTrends()
getPlaceTrends()
getAllUserLists()
getUserLists()
getAvailableTrends(GeoLocation)
getClosestTrends(GeoLocation)
getFavorites(int)
getFavorites(Paging paging)
getBlockingUsers()
getBlocksList(cursor)
getPublicTimeline()
N/A
AccountTotals getAccountTotals()
N/A
IDs getNoRetweetIds()
N/A
IDs getRetweetedByIDs(long)
N/A
IDs getRetweetedByIDs(long, Paging)
N/A
getRetweetedByMe()
N/A
getRetweetedByUser()
N/A
getRetweetedToMe()
N/A
getRetweetedToUser()
N/A
getRetweetsOfMe()
N/A
getDailyTrends()
N/A
getWeeklyTrends()
N/A
getRetweetedBy()
N/A
boolean existsBlock()
N/A
boolean existsFriendship()
N/A
boolean test()
N/A

Updating Twitter4j jar file in Android Application

step 1:-
Open You existing project Right click on Project folder >> property>>Java Build Path>>library>> select previous Twitter4j-core file >> click on remove

Now Copay and paste Twitter4j-core-3.0.3 jar file in your existing project libs folder and do the following
right click on Project >> properties>>java Build Path>>library>> add Jar >> choose your project libs folder >.select the Twitter4j-core-3.0.3 file and >> apply.

Step 2
After performing step first and go into your src folder source code and modify the required method if needed as per above given table.This the basic way to you update existing twitter integration in android.
Now I am going to show a simple integration of Twitter in android
 Step 1.
You need to create a following classes and xml file for this integration:-
1. TwitterHomeActivity (main class)
2. ConnectionDetector( For checking Internate connection)
3. AlertDialogManager ( For Alert Message)
4. activity_twitter_home.xml( mail activity class xml)

Step 2
Use following code for this integration:-
public class AlertDialogManager {

public void showAlertDialog(Context context, String title, String message, Boolean status) {
    AlertDialog alertDialog = new AlertDialog.Builder(context).create();

    // Setting Dialog Title
    alertDialog.setTitle(title);

    // Setting Dialog Message
    alertDialog.setMessage(message);

    if(status != null)
        // Setting alert dialog icon
        alertDialog.setIcon((status) ? R.drawable.success : R.drawable.fail);

    // Setting OK Button
    alertDialog.setButton("OK", new DialogInterface.OnClickListener() {
        public void onClick(DialogInterface dialog, int which) {
        }
    });

    // Showing Alert Message
    alertDialog.show();
}}

public class ConnectionDetector {

private Context _context;

public ConnectionDetector(Context context){
    this._context = context;
}
public boolean isConnectingToInternet(){
    ConnectivityManager connectivity = (ConnectivityManager) _context.getSystemService(Context.CONNECTIVITY_SERVICE);
      if (connectivity != null)
      {
          NetworkInfo[] info = connectivity.getAllNetworkInfo();
          if (info != null)
              for (int i = 0; i < info.length; i++)
                  if (info[i].getState() == NetworkInfo.State.CONNECTED)
                  {
                      Log.d("Network", "NETWORKnAME: "+info[i].getTypeName());
                      return true;
                  }

      }
      return false;
}}
 Android Manifest file look like this
<?xml version="1.0" encoding="utf-8"?>
<uses-sdk
    android:minSdkVersion="6"
    android:targetSdkVersion="8" />
<!-- Permission - Internet Connect -->
<uses-permission android:name="android.permission.INTERNET" />

<!-- Network State Permissions -->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

<application
    android:allowBackup="true"
    android:icon="@drawable/ic_launcher"
    android:label="@string/app_name"
    android:theme="@style/AppTheme" >
    <activity
        android:name="com.sks.twitter.TwitterHomeActivity"
        android:label="@string/app_name" >
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

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

            <category android:name="android.intent.category.DEFAULT" />
            <category android:name="android.intent.category.BROWSABLE" />

            <data
                android:host="t4jsample"
                android:scheme="oauth" />
        </intent-filter>
    </activity>
</application>
 Activity_twitter_home.xml look like this
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".TwitterHomeActivity" >

<TextView
    android:id="@+id/textView1"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentLeft="true"
    android:layout_alignParentTop="true"
    android:layout_marginLeft="106dp"
    android:layout_marginTop="21dp"
    android:text="@string/hello_world"
    android:textColor="#A52A2A"
    android:textStyle="bold"
    android:typeface="serif" />

<Button
    android:id="@+id/button1"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignLeft="@+id/textView1"
    android:layout_below="@+id/textView1"
    android:layout_marginTop="80dp"
    android:text="Login to twitter" />

<EditText
    android:id="@+id/editText1"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_centerHorizontal="true"
    android:layout_centerVertical="true"
    android:visibility="gone"
    android:ems="10" />

<Button
    android:id="@+id/button2"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_below="@+id/editText1"
    android:layout_centerHorizontal="true"
    android:layout_marginTop="34dp"
    android:visibility="gone"
    android:text="Tweets" />
 Finally TwitterHomeActivity code
public class TwitterHomeActivity extends Activity {
    static String TWITTER_CONSUMER_KEY = "marlVCZaLYAG52rVvholRw"; 
static String TWITTER_CONSUMER_SECRET = "5uZZFboHSK9psBPsqJUDSb1GuC36Fy83cYornOPu9A"; 
static String PREFERENCE_NAME = "twitter_oauth";
static final String PREF_KEY_OAUTH_TOKEN = "oauth_token";
static final String PREF_KEY_OAUTH_SECRET = "oauth_token_secret";
static final String PREF_KEY_TWITTER_LOGIN = "isTwitterLogedIn";
static final String TWITTER_CALLBACK_URL = "oauth://t4jsample";
static final String URL_TWITTER_AUTH = "auth_url";
static final String URL_TWITTER_OAUTH_VERIFIER = "oauth_verifier";
static final String URL_TWITTER_OAUTH_TOKEN = "oauth_token";

ProgressDialog pDialog;
private static Twitter twitter;
private static RequestToken requestToken;
private static SharedPreferences mSharedPreferences;
private ConnectionDetector cd;
AlertDialogManager alert = new AlertDialogManager();
EditText sts;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_twitter_home);
    setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);


    cd = new ConnectionDetector(getApplicationContext());
    if (!cd.isConnectingToInternet()) {
        alert.showAlertDialog(TwitterHomeActivity.this, "Internet Connection Error",
                "Please connect to working Internet connection", false);
        return;
    }
    // Check if twitter keys are set
    if(TWITTER_CONSUMER_KEY.trim().length() == 0 || TWITTER_CONSUMER_SECRET.trim().length() == 0){
        alert.showAlertDialog(TwitterHomeActivity.this, "Twitter oAuth tokens", "Please set your twitter oauth tokens first!", false);
        return;
    }
    mSharedPreferences = getApplicationContext().getSharedPreferences("MyPref", 0);

    findViewById(R.id.button1).setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {
            loginToTwitter();
        }
    });
    findViewById(R.id.button2).setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {
            sts = (EditText)findViewById(R.id.editText1);
            String status = sts.getText().toString();
            if (status.trim().length() > 0) {
                new updateTwitterStatus().execute(status);
            } else {
                Toast.makeText(getApplicationContext(),
                        "Please enter status message", Toast.LENGTH_SHORT).show();
            }

        }
    });

    if (!isTwitterLoggedInAlready()) {
        Uri uri = getIntent().getData();
        if (uri != null && uri.toString().startsWith(TWITTER_CALLBACK_URL)) {
            String verifier = uri.getQueryParameter(URL_TWITTER_OAUTH_VERIFIER);
            try {
                AccessToken accessToken = twitter.getOAuthAccessToken(requestToken, verifier);
                // Shared Preferences
                Editor e = mSharedPreferences.edit();
                e.putString(PREF_KEY_OAUTH_TOKEN, accessToken.getToken());
                e.putString(PREF_KEY_OAUTH_SECRET,accessToken.getTokenSecret());
                e.putBoolean(PREF_KEY_TWITTER_LOGIN, true);
                e.commit();

                Log.e("Twitter OAuth Token", "> " + accessToken.getToken());

                findViewById(R.id.button1).setVisibility(View.GONE);
                findViewById(R.id.editText1).setVisibility(View.VISIBLE);
                findViewById(R.id.button2).setVisibility(View.VISIBLE);

                long userID = accessToken.getUserId();
                User user = twitter.showUser(userID);
                String username = user.getName();
                Log.e("UserID: ", "userID: "+userID+""+username);
                Log.v("Welcome:","Thanks:"+Html.fromHtml("<b>Welcome " + username + "</b>"));
            } catch (Exception e) {
                Log.e("Twitter Login Error", "> " + e.getMessage());
            }
        }
    }
}

private void loginToTwitter() {
    if (!isTwitterLoggedInAlready()) {
        ConfigurationBuilder builder = new ConfigurationBuilder();
        builder.setOAuthConsumerKey(TWITTER_CONSUMER_KEY);
        builder.setOAuthConsumerSecret(TWITTER_CONSUMER_SECRET);
        Configuration configuration = builder.build();

        TwitterFactory factory = new TwitterFactory(configuration);
        twitter = factory.getInstance();

        try {
            requestToken = twitter.getOAuthRequestToken(TWITTER_CALLBACK_URL);
            this.startActivity(new Intent(Intent.ACTION_VIEW, 
                    Uri.parse(requestToken.getAuthenticationURL())));
        } catch (TwitterException e) {
            e.printStackTrace();
        }
    } else {
        Toast.makeText(getApplicationContext(),
                "Already Logged into twitter", Toast.LENGTH_LONG).show();
    }
}
private boolean isTwitterLoggedInAlready() {
    return mSharedPreferences.getBoolean(PREF_KEY_TWITTER_LOGIN, false);
}
class updateTwitterStatus extends AsyncTask<String, String, String> {
    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        pDialog = new ProgressDialog(TwitterHomeActivity.this);
        pDialog.setMessage("Updating to twitter...");
        pDialog.setIndeterminate(false);
        pDialog.setCancelable(false);
        pDialog.show();
    }
    protected String doInBackground(String... args) {
        Log.d("Tweet Text", "> " + args[0]);
        String status = args[0];
        try {
            ConfigurationBuilder builder = new ConfigurationBuilder();
            builder.setOAuthConsumerKey(TWITTER_CONSUMER_KEY);
            builder.setOAuthConsumerSecret(TWITTER_CONSUMER_SECRET);
            // Access Token 
            String access_token = mSharedPreferences.getString(PREF_KEY_OAUTH_TOKEN, "");
            // Access Token Secret
            String access_token_secret = mSharedPreferences.getString(PREF_KEY_OAUTH_SECRET, "");

            AccessToken accessToken = new AccessToken(access_token, access_token_secret);
            Twitter twitter = new TwitterFactory(builder.build()).getInstance(accessToken);

            // Update status
            twitter4j.Status response = twitter.updateStatus(status);

            Log.d("Status", "> " + response.getText());
        } catch (TwitterException e) {
            // Error in updating status
            Log.d("Twitter Update Error", e.getMessage());
        }
        return null;
    }
    protected void onPostExecute(String file_url) {
        // dismiss the dialog after getting all products
        pDialog.dismiss();
        // updating UI from Background Thread
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                Toast.makeText(getApplicationContext(),
                        "Status tweeted successfully", Toast.LENGTH_SHORT)
                        .show();
                // Clearing EditText field
                sts.setText("");
            }
        });
    }

}}
Refrence Link for more detail:--
https://dev.twitter.com/blog/changes-coming-to-twitter-api
https://dev.twitter.com/docs/api/1.1/overview
https://dev.twitter.com/blog/planning-for-api-v1-retirement
http://twitter4j.org/en/versions.html#migration22x-30x
https://groups.google.com/forum/?fromgroups#!forum/twitter4j
                   Happy Coding!!!

Build a Custom Kernel Module for Android

Hi Guys!!!Hope you are doing well !!!. Today I will describe how you can write a custom kernel module(Hello world) for Android and load it a...