I am working on deeplinking part in android, I have found branch.io provides deeplinking support. I followed everything as per documentation but still it is opening custom link instead of app.
code:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="branch.next.com.newbranchapp">
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
<application
android:name="io.branch.referral.BranchApp""
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity android:name=".MainActivity"
android:launchMode="singleTask"
>
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
<!-- Branch URI scheme -->
<intent-filter>
<data android:scheme="branch" android:host="open" />
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
</intent-filter>
</activity>
<!-- Branch init -->
<!-- Branch init -->
<meta-data android:name="io.branch.sdk.BranchKey" android:value="key_live_abFuXvh4EU7Yocf2FB4jJpccAEcz3sZT" />
<meta-data android:name="io.branch.sdk.BranchKey.test" android:value="key_test_cbvEXCcXuJ27ojf1yu9sTkaitsoF0v9X" />
<!-- Branch testing (TestMode "true" to simulate fresh installs on dev environment) -->
<meta-data android:name="io.branch.sdk.TestMode" android:value="true" />
<!-- Branch install referrer tracking -->
<receiver android:name="io.branch.referral.InstallListener" android:exported="true">
<intent-filter>
<action android:name="com.android.vending.INSTALL_REFERRER" />
</intent-filter>
</receiver>
</application>
</manifest>
public class MainActivity extends AppCompatActivity
{
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
#Override
public void onStart() {
super.onStart();
Branch branch = Branch.getInstance();
branch.initSession(new Branch.BranchUniversalReferralInitListener() {
#Override
public void onInitFinished(BranchUniversalObject branchUniversalObject, LinkProperties linkProperties, BranchError error) {
if (error == null) {
Log.i("MyApp","not working");
} else {
Log.i("MyApp", error.getMessage());
}
}
}, this.getIntent().getData(), this);
}
#Override
public void onNewIntent(Intent intent) {
this.setIntent(intent);
}
}
// application
public class CustomApplication extends Application
{
#Override
public void onCreate()
{
super.onCreate();
Branch.getAutoInstance(this);
}
}
Amruta from Branch.io here:
Two things:
The name of your Application class is "CustomApplication" but in your Manifest I see the name for your Application class set to "android:name="io.branch.referral.BranchApp"". I am not sure but I believe this should give you errors in your App. This should be set to ".CustomApplication"
I just took a quick look at your Branch dashboard. Since you are testing with a link from the test version of your app (Links from the test version have the link domain of the type ".test-app.link") you should populate the Android URL for the test version in your Link Settings. You can switch between the 'Live' and 'Test' using the flipper on the top-left corner of the dashboard.
Related
after using react-native-bootsplash library, my app takes time to launch for the first time, and also after submitting the releasing version on the play store, I'm getting Pre-Launch report as: Your app took 22,761ms to launch for the first time.
I also noticed the same on the iOS too, here is my configuration:
My MainActivity.java file:
package com.qadaapp;
import com.facebook.react.ReactActivity;
import com.facebook.react.ReactActivityDelegate;
import com.facebook.react.ReactRootView;
import android.os.Bundle;
import com.zoontek.rnbootsplash.RNBootSplash;
public class MainActivity extends ReactActivity {
/**
* Returns the name of the main component registered from JavaScript. This is used to schedule
* rendering of the component.
*/
#Override
protected String getMainComponentName() {
return "Qadaapp";
}
/**
* Returns the instance of the {#link ReactActivityDelegate}. There the RootView is created and
* you can specify the renderer you wish to use - the new renderer (Fabric) or the old renderer
* (Paper).
*/
#Override
protected ReactActivityDelegate createReactActivityDelegate() {
return new MainActivityDelegate(this, getMainComponentName());
}
public static class MainActivityDelegate extends ReactActivityDelegate {
public MainActivityDelegate(ReactActivity activity, String mainComponentName) {
super(activity, mainComponentName);
}
#Override
protected ReactRootView createRootView() {
ReactRootView reactRootView = new ReactRootView(getContext());
// If you opted-in for the New Architecture, we enable the Fabric Renderer.
reactRootView.setIsFabric(BuildConfig.IS_NEW_ARCHITECTURE_ENABLED);
return reactRootView;
}
#Override
protected boolean isConcurrentRootEnabled() {
// If you opted-in for the New Architecture, we enable Concurrent Root (i.e. React 18).
// More on this on https://reactjs.org/blog/2022/03/29/react-v18.html
return BuildConfig.IS_NEW_ARCHITECTURE_ENABLED;
}
}
#Override
protected void onCreate(Bundle savedInstanceState) {
RNBootSplash.init(this);
super.onCreate(null);
}
}
My AndroidMainfest.file:
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.qadaapp">
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="com.android.vending.BILLING"/>
<application android:name=".MainApplication" android:label="#string/app_name" android:icon="#mipmap/ic_launcher" android:roundIcon="#mipmap/ic_launcher_round" android:allowBackup="false" android:usesCleartextTraffic="true" android:theme="#style/BootTheme">
<activity android:name=".MainActivity" android:label="#string/app_name" android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|screenSize|smallestScreenSize|uiMode" android:launchMode="singleTask" android:windowSoftInputMode="adjustResize" android:exported="true">
<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:scheme="qadaapp"/>
</intent-filter>
</activity>
<activity android:name="com.facebook.FacebookActivity" android:configChanges="keyboard|keyboardHidden|screenLayout|screenSize|orientation" android:label="#string/app_name"/>
<activity android:name="com.facebook.CustomTabActivity" android:exported="true">
<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:scheme="#string/fb_login_protocol_scheme"/>
</intent-filter>
</activity>
<meta-data android:name="com.facebook.sdk.ApplicationId" android:value="#string/facebook_app_id"/>
<meta-data android:name="com.facebook.sdk.ClientToken" android:value="#string/facebook_client_token"/>
<meta-data
android:name="preloaded_fonts"
android:resource="#array/preloaded_fonts" />
</application>
</manifest>
My styles.xml file:
<resources>
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.DayNight.NoActionBar">
<!-- Customize your theme here. -->
<item name="android:editTextBackground">#drawable/rn_edit_text_material</item>
</style>
<!-- BootTheme should inherit from Theme.SplashScreen -->
<style name="BootTheme" parent="Theme.SplashScreen">
<item name="windowSplashScreenBackground">#color/bootsplash_background</item>
<item name="windowSplashScreenAnimatedIcon">#mipmap/bootsplash_logo</item>
<item name="postSplashScreenTheme">#style/AppTheme</item>
</style>
</resources>
Also I added this in my build.gradle file:
implementation "androidx.core:core-splashscreen:1.0.0"
My App.js:
const unsubscribe = auth().onUserChanged(async usr => {
if (!usr) {
await _getSlideShows();
setUser(null);
return RNBootSplash.hide({fade: true});
}
if (usr?.uid) {
let dbResult = await DB.collection('users').doc(usr?.uid).get();
setUser(usr);
if (dbResult?.exists) {
let dbUser = dbResult.data();
setUser(dbUser);
}
return RNBootSplash.hide({fade: true});
}
});
return () => unsubscribe();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
When I was not using react-native-bootsplash, the app was working fast, however when I implemeneted the react-native-boot-splash library, my app's cold start time increased on both the platforms.
I want to change my default dialer app and searched for some articles.
But when I'm in the test, I encounter problem my real phone(Android 6.0) doesn't show the pop window.
InRealPhoneTest.png
So I'm attempting to test in a virtual machine(android 6.0), it works perfectly.
InVirtualMachineTest.png
below are my codes:
Application.xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.slb.test1">
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity
android:name=".MainActivity"
android:label="#string/app_name"
android:directBootAware="true"
android:excludeFromRecents="true"
android:launchMode="singleInstance"
android:process=":interim"
android:resizeableActivity="true"
android:screenOrientation="nosensor">
<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"/>
<action android:name="android.intent.action.DIAL"/>
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.BROWSABLE"/>
<data android:scheme="tel"/>
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.DIAL"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</activity>
</application>
MainApplication.java
public class MainActivity extends AppCompatActivity {
private static final int REQUEST_CODE_SET_DEFAULT_DIALER = 289;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void ViewClick(View view){
try {
Intent intent = new Intent(TelecomManager.ACTION_CHANGE_DEFAULT_DIALER);
intent=intent.putExtra(TelecomManager.EXTRA_CHANGE_DEFAULT_DIALER_PACKAGE_NAME, getPackageName());
startActivityForResult(intent, REQUEST_CODE_SET_DEFAULT_DIALER);
}catch (Exception e){
e.printStackTrace();
}
}
#Override
protected void onActivityResult(int requestCode, int resultCode, #Nullable Intent data) {
if(requestCode==REQUEST_CODE_SET_DEFAULT_DIALER){
if(resultCode==RESULT_OK){
Toast.makeText(this,"accept",Toast.LENGTH_SHORT).show();
}else if(resultCode==RESULT_CANCELED){
Toast.makeText(this,"cancel",Toast.LENGTH_SHORT).show();
}else{
Toast.makeText(this,"unknown",Toast.LENGTH_SHORT).show();
}
}
}}
My purpose wants to change the default app dialer through InCallService service class, I'm just testing the pop window.
when I process program in a virtual machine of android 6.0, I can choose whether to accept or cancel in a popout. however, when I process program in a real phone that version is android 6.0, the phone doesn't appear the popout.
So, I can't understand why it doesn't work on the real phone. can you tell me something about it?. your answer will be appreciated.
I have my manifest in check, my services in check, my dependencies in check, class variables in check and still no notifications on my device. I'm using my computer to send firebase cloud messages and I should be receiving them on my android phone. However,my android phone is not picking up the notifications. And yes, my android device is in the background as I send the message. Anyone know what my problem is?
Here's the source code:
My Service
public class FirebaseIDMessage extends FirebaseMessagingService {
private static final String TAG = "FirebaseIDMessage";
#Override
public void onNewToken(String s) {
super.onNewToken(s);
String token = s;
Log.d(TAG, "Registered token: = " + token);
sendRegistrationToServer(token);
}
private void sendRegistrationToServer(String token){
}
}
My Manifest File
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.messaging">
<uses-permission android:name="android.permission.INTERNET" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<!-- Services -->
<service android:name=".FirebaseIDMessage"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT"/>
</intent-filter>
</service>
<activity android:name=".MessagingActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
My Activity
public class MessagingActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_messaging);
}
}
In your manifest file, you are missing INSTANCE_ID_EVENT
<intent-filter>
<action android:name="com.google.firebase.INSTANCE_ID_EVENT" />
</intent-filter>
This is the intent-filter for the Class extended with FirebaseInstanceIdService
public class MyFirebaseInstanceIdService extends FirebaseInstanceIdService
{
public static final String REGISTRATION_TOKEN = "REG_TOKEN";
#Override
public void onTokenRefresh()
{
String token = FirebaseInstanceId.getInstance().getToken();
Log.e(REGISTRATION_TOKEN,token);
}
}
So, finally the manifest service will be like
<service android:name=".Utils.PushNotification.MyFirebaseInstanceIdService">
<intent-filter>
<action android:name="com.google.firebase.INSTANCE_ID_EVENT" />
</intent-filter>
</service>
On the log you would have got registered Token. Your all set only if you receive that token.
Goto Firebase console : https://console.firebase.google.com
Choose your project -> From the left side menu -> Choose Cloud Messaging -> New Message
Type your message and then in the TARGET choose Single Device and then copy paste your received token and check on your device for this notification by this way we can confirm you have set all notification related code correctly. If you still face any problem please let know so that I can share some samples.
Here´s my problem:
my Android app registers a boot receiver, which initializes a PushNotification-Manager (PushWoosh).
This is because even after a reboot of the device, the user should be able to receive push notifications without having to start the app manually.
This works, but when the device is rebooted, the apps main activity (MainMenuActivity) is launched and brought to the foreground, which should not happen.
Here´s the involved code:
AndroidManifest.xml:
<!-- Re-register PushManagers after reboot -->
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#android:style/Theme.Black.NoTitleBar">
<!-- PushWoosh -->
<activity android:name="com.arellomobile.android.push.PushWebview"/>
<activity android:name="com.arellomobile.android.push.MessageActivity"/>
<activity android:name="com.arellomobile.android.push.PushHandlerActivity"/>
<!-- PushWoosh -->
<receiver
android:name="com.google.android.gcm.GCMBroadcastReceiver"
android:permission="com.google.android.c2dm.permission.SEND">
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE"/>
<action android:name="com.google.android.c2dm.intent.REGISTRATION"/>
<category android:name="de.myapp.android"/>
</intent-filter>
</receiver>
<!-- PushWoosh -->
<service android:name="com.arellomobile.android.push.PushGCMIntentService"/>
<!-- Boot-Receiever -->
<receiver android:name="de.myapp.android.startup.BootCompleteReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
</intent-filter>
</receiver>
<activity
android:name="de.myapp.android.activity.MainMenuActivity"
android:configChanges="orientation|keyboardHidden|screenSize"
android:label="#string/app_name"
android:launchMode="singleTop"
android:screenOrientation="portrait"
android:windowSoftInputMode="adjustPan">
<intent-filter>
<!-- Starten bei Klick auf Launcher Icon -->
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
<intent-filter>
<!-- Starten bei Erhalt einer Push Notification -->
<action android:name="de.myapp.android.MESSAGE"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</activity>
BootCompleteReceiver.java:
public class BootCompleteReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent i) {
PushWooshHelper.setupPushNotifications(context.getApplicationContext());
}
}
PushWooshHelper.java:
public class PushWooshHelper {
public static void setupPushNotifications(Context context) {
PushManager pushManager = new PushManager(context, AppIDs.PUSHWOOSH_APP_ID, AppIDs.GCM_PROJECT_ID);
pushManager.onStartup(context);
pushManager.startTrackingGeoPushes();
}
}
MainMenuActivity.java:
public class MainMenuActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
...
}
private void checkMessage(Intent intent) {
if (intent != null) {
String log = "PUSH NOTIFICATION RECEIVED.";
if (intent.hasExtra(PushManager.PUSH_RECEIVE_EVENT)) {
log += "message: " + intent.getExtras().getString(PushManager.PUSH_RECEIVE_EVENT);
}
else if (intent.hasExtra(PushManager.REGISTER_EVENT)) {
log += "<register>";
}
else if (intent.hasExtra(PushManager.UNREGISTER_EVENT)) {
log += "<unregister>";
}
else if (intent.hasExtra(PushManager.REGISTER_ERROR_EVENT)) {
log += "<register error>";
}
else if (intent.hasExtra(PushManager.UNREGISTER_ERROR_EVENT)) {
log += "<unregister error>";
}
}
}
#Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
setIntent(intent);
checkMessage(intent);
setIntent(new Intent());
}
}
Please note: I do not have access to PushManager.onStartup(), since it is provided by PushWoosh.
Any help is greatly appreciated!
That's strange. Pushwoosh uses GCM which works after restart of the device out of the box. You just have to register for the push notifications once and then after restart GCM takes care about that itself.
I am trying to integrate an open source app into my android app. I have made the open source app as a library app and integrated the xml into my android manifest file as well. There are no compile errors.
First Screen is the login screen for the library app and when it is called it is throwing java lang class exception error at:
m_app = (TodoApplication) getApplication();
source code of loginscreen.java:
public class LoginScreen extends Activity {
final static String TAG = LoginScreen.class.getSimpleName();
private TodoApplication m_app;
private Button m_LoginButton;
private BroadcastReceiver m_broadcastReceiver;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.login);
m_app = (TodoApplication) getApplication();
// supposed to help with the banding on the green background
findViewById(R.id.loginbackground).getBackground().setDither(true);
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction("com.todotxt.todotxttouch.ACTION_LOGIN");
m_broadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
Intent i = new Intent(context, TodoTxtTouch.class);
startActivity(i);
finish();
}
};
registerReceiver(m_broadcastReceiver, intentFilter);
m_LoginButton = (Button) findViewById(R.id.login);
m_LoginButton.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
login();
}
});
//final RemoteClient remoteClient = m_app.getRemoteClientManager()
// .getRemoteClient();
//if (remoteClient.isAuthenticated()) {
switchToTodolist();
//}
}
private void switchToTodolist() {
Intent intent = new Intent(this, TodoTxtTouch.class);
startActivity(intent);
finish();
}
#Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(m_broadcastReceiver);
}
void login() {
final RemoteClient client = m_app.getRemoteClientManager()
.getRemoteClient();
if (!client.isAvailable()) {
Log.d(TAG, "Remote service " + client.getClass().getSimpleName()
+ " is not available; aborting login");
Util.showToastLong(m_app, R.string.toast_login_notconnected);
} else {
RemoteLoginTask loginTask = client.getLoginTask();
loginTask.showLoginDialog(this);
}
}
}
Integrated library code in android manifest.xml:
<activity android:name="com.todotxt.todotxttouch.LoginScreen" android:label="#string/app_label"
android:theme="#android:style/Theme.NoTitleBar"
android:configChanges="keyboardHidden|orientation">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
<category android:name="com.todotxt.todotxttouch.category.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name="com.todotxt.todotxttouch.TodoApplication" />
<activity android:name="com.todotxt.todotxttouch.Filter" android:label="Filter"
android:theme="#android:style/Theme.NoTitleBar" />
<activity android:name="com.todotxt.todotxttouch.Preferences" android:label="#string/set_preferences" />
<activity android:name="com.todotxt.todotxttouch.AddTask" android:label="#string/addtask"
android:theme="#android:style/Theme.NoTitleBar"
android:configChanges="orientation|keyboardHidden"
android:windowSoftInputMode="adjustResize">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
</intent-filter>
</activity>
<activity-alias android:name="com.todotxt.todotxttouch.AddTaskShortcut"
android:targetActivity="com.todotxt.todotxttouch.AddTask" android:label="#string/shortcut_addtask_name">
<intent-filter>
<action android:name="android.intent.action.CREATE_SHORTCUT" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity-alias>
<activity-alias android:name="com.todotxt.todotxttouch.AddTaskShare"
android:targetActivity="com.todotxt.todotxttouch.AddTask" android:label="#string/share_addtask_name">
<intent-filter>
<action android:name="android.intent.action.SEND" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="text/plain" />
</intent-filter>
</activity-alias>
<activity android:name="com.todotxt.todotxttouch.HelpActivity"
android:theme="#android:style/Theme.Translucent.NoTitleBar.Fullscreen" />
<activity android:name="com.todotxt.todotxttouch.TodoTxtTouch" android:theme="#android:style/Theme.NoTitleBar"
android:configChanges="keyboardHidden|orientation">
<intent-filter>
<action android:name="android.intent.action.SEARCH" />
</intent-filter>
<meta-data android:name="android.app.searchable"
android:resource="#xml/searchable" />
</activity>
Could anyone please help me on understanding the problem.
Let me explain further: I am having a file called Todoapplication.java....so the class exists...it being called from LoginScreen.java as
m_app = (TodoApplication) getApplication();
and that is where I am getting java lang class exception?
Activity.getApplication() returns an instance of the application class that was declared in the manifest in the <application> element. I don't see it in your pasted manifest.
It's not enough to simply have the application class in your app. It must be explicitly designated as one in the manifest.
I maybe getting the wrong end of the stick so I beg the programming gods for forgiveness in advance.
Assuming you are developing in Eclipse, is this not a simple case of having a project in Eclipse with the open source source in, which within the project properties has the option isLibrary ticked.
In YOUR project's properties you can add a library and Eclipse will list the open source one (and any others that have the "isLibrary" checked). Would you not simply select the open source project and add it. Your project will then add the library and build again?
To access the open source project, now a library, you can use "import" statements to access any public methods that are exposed.
A good example of this setup process using an open source library project is Actionbar Sherlock to which I wrote a tutorial youtube that demonstrates visually what I have just written. It can be found at http://www.youtube.com/watch?v=avcp6eD_X2k