getExtras() return null on Application level (-class) - android

On my Application level I receive null for getExtras(), but on Activity level i can see them correctly.
public class MyApplication extends Application
{
#Override
public void onCreate() {
super.onCreate();
Intent intent = getPackageManager().getLaunchIntentForPackage("com.example.MyApp");
if (intent != null){
String mStaticWorldUrl = intent.getStringExtra("arg1Name");
String mStaticWorldIconUrl = intent.getStringExtra("arg2Name");
Log.i("LOG", mStaticWorldUrl + " --- " + mStaticWorldIconUrl);
}
}
}
I'm calling the app from some shortcuts that were created by this code:
(- each shortcut has different Extras sent to the Intent)
// create a shortcut for the specific app
public static void createShortcutForPackage(Context context,
String packageName, String className, String shortcutName,
String arg1Name, String arg1Val, String arg2Name, String arg2Val,
int iconID) {
Intent intent = new Intent();
intent.setComponent(new ComponentName(packageName, className));
PackageManager pm = context.getPackageManager();
Context pkgContext = createPackageContext(context, packageName);
if (pkgContext == null)
return;
Intent shortcut = new Intent("com.android.launcher.action.INSTALL_SHORTCUT");
Intent shortcutIntent = pm.getLaunchIntentForPackage(packageName);
if (arg1Name != null)
shortcutIntent.putExtra(arg1Name, arg1Val);
if (arg2Name != null)
shortcutIntent.putExtra(arg2Name, arg2Val);
shortcut.putExtra(Intent.EXTRA_SHORTCUT_INTENT, shortcutIntent);
shortcut.putExtra(Intent.EXTRA_SHORTCUT_NAME, shortcutName);
shortcut.putExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE,Intent.ShortcutIconResource.fromContext(context, iconID));
shortcut.putExtra("duplicate", false);
context.sendBroadcast(shortcut);
}
how can I read these Extras on the Application level?
or is there any other way to create different shortcuts for application and read its' "parameters" data on Application?

The Application class is static for the application: there is only ever a single instance of it for your app's process. If your app has been launched with a normal launch Intent, rather than a shortcut you created, then no extras would be present. The app process does not die when HOME or BACK is pressed, so the Intent used to launch the package may not be what you think it should be.
You should not need to look at the Intent at the Application level. Intent objects are not intended to be "sent" there, but rather to an Activity, Service or BroadcastReceiver.

This is conceptual error which facing to get data in application class using getExtra which is the method of Intent
Reason for this issue:
No extras is because the queried intent was one that was generated
one line earlier, it is the intent that the OS has generated for the
package as requested in the following code: Intent intent =
getPackageManager().getLaunchIntentForPackage("com.example.M‌​yApp");
Intent objects within an Application class instance: they are not
delivered there
Let's understand following things to use in upcoming usage while anyone want to get data in application level
What is Intent ?
What is the Use of Intent?
What other things can we use to achieve this?
What is Intent?
An Intent provides a facility for performing Late runtime binding between the code in different applications . Its most significant use is in the launching of activities, where it can be thought of as the glue between activities. It is basically a passive data structure holding an abstract description of an action to be performed.
extras - This is a Bundle of any additional information. This can be used to provide extended information to the component. For example, if we have a action to send an e-mail message, we could also include extra pieces of data here to supply a subject, body, etc.
What is the Use of Intent?
Use to intents facilitate communication between components in several ways, Followings are standard use
To start an activity.
To start a service.
To deliver a broadcast
What other things can we use to achieve this?
There are lots of things we can use to achive this and solved this
issue.
But right now here i mentioned only one which is standard and secured
to use application
Content provider: To offer a file from your app to another app is to
send the receiving app the file's content URI and grant temporary
access permissions to that URI. Content URIs with temporary URI
access permissions are secure because they apply only to the app that
receives the URI, and they expire automatically.

Related

Android capture data from intent

I have an app that sends intent to an exact app. I have root shell access and could possibly modify AOSP, but I don't really know where to look at.
Got this in logcat:
START u0 {act=com.app.Action.OPEN cmp=com.app/.SomeActivity (has
extras)} from uid 10052
How to capture this (has extras)? Or at least keys (not values) used in intent, cause my main goal is to start external app activity with parameters (with root access), but it is closed source and I don't know how extra string key is named.
To clarify the question I should say that intent is called from an app to itself and I don't have sources of this app.
one possible way to get hold of the intent data is the create a package with exactly the same package name and intent filters set up, and then replace the original package with the fake package, as the new intent receiver. only then the solution provided in this answer could be used - because unless an intent is being received, there is nothing to list.
while being able to build AOSP from source, you still could edit class Intent and add further logging. Uri mData appears to be the data you'd be looking for; where the one constructor in line 6130 seems to be the one most commonly used:
Intent(String action, Uri uri, Context packageContext, Class<?> cls)
therefore it should be possible to log from within that constructor (the if condition is optional):
public Intent(String action, Uri uri, Context packageContext, Class<?> cls) {
setAction(action);
mData = uri;
mComponent = new ComponentName(packageContext, cls);
if(cls.getSimpleName().equals("SomeActivity")) {
Log.d("Intent", "has leaked: " + action + ": " + uri.toString());
}
}

Different types of Android Intents

I have recently started a new Android project and I'm working off the previous developer's code. I'm relatively new to Android and I've come across something that I'm unsure of.
What is the difference between this:
Intent intent = new Intent("com.example.project.MENU");
and this:
Intent intent = new Intent(this, DisplayMenu.class);
I understand what the 2nd code snippet does, I just can't get my head around as to what the first one is doing? Is it referencing the file in the package? Thanks
The first one is an implicit intent, while the second is an explicit intent.
The first one fired an Intent for the action com.example.project.MENU. If you look inside you project AndroidManifest.xml you can see some <intent-filter> balise. This baslise register activity, service or broadcast receiver to different actions.
This mecanism can be used to allow third party app to launch some of your activities.
You can see more on this tutorial http://www.vogella.com/tutorials/AndroidIntent/article.html#intenttypes
Basically an Intent carries some information that are used by the system in order to determine which component should be called for executing the action.
These information are:
Component name: the name of the component that should be launched. (If present the Intent is Explicit)
Action: it specifies the generic action that should be executed (es. ACTION_VIEW, ACTION_SEND). It determines how the rest of the intent is strucutred.
Data: represents the URI that refers to the object that should be associated with the action. For example with the action ACTION_EDIT, the Data should contain the URI of the document that you want modify.
Category: Additional infromation (for example if you want that your app is shown in the launcher you can use CATEGORY_LAUNCHER)
Extras: keys-values pairs that carries additional information
Flags: it is like a metadata that specify how the intent should be managed by the system.
The Intent class provides a lot of different constructors.
The first one you asked for is public Intent (String action)
So, this sets the Action, and lets null all other fields.
The second one public Intent (Context packageContext, Class<?> cls) creates an intent for a specific component by its Component name. All other fields are null. This is a Explicit Intent, since you declare exactly which component should receive it.
The first one is used when you need to call Intent from System
such as Open Camera, Gallery, or Share something to other Application
for example
// this one call Camera to Capture Image
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
// this one call gallery to let you select image
Intent intent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
and That MediaStore.something here is just a Path to the system
for example
MediaStore.ACTION_IMAGE_CAPTURE = "android.media.action.IMAGE_CAPTURE"
Intent.ACTION_PICK = "android.intent.action.PICK"
The first type of intent is mostly used if you want to open another application from your application while the second type of intent is used to open another activity in your application.

Get calling activity from some other activity

I am calling an activity from another activity by this code:
Intent intent = new Intent(context, mClass);
context.startActivity(intent);
and from my new activity which is started by this code. I want to know which activity starts this activity. I used this code for this purpose
Intent intent = getIntent();
Class<?> c = intent.getClass();
if (c != OffersActivity.class) {
prepareForNotifications();
setListAdapter();
}
but by this code I am not able to get the classname which starts this activity. I really need some help.
thanks
There is a method getCallingActivity(), but that only works, if the calling activity calls you with startActivityForResult(). I have seen libraries use that and say that you must call them that way, but frankly it is a bit nasty. The simple answer is that you're not supposed to know. Android is a system of loosely coupled activities and the calling activity should thus have no real meaning to your activity. Any information your activity needs should be put explicitly in the intent, so if you really want to know who called you then the caller needs to put that extra in. You won't be able to tell if they are lying of course, so don't go trying to use this for anything security-related. However, I would suggest that whatever you're determining based on the caller, is what the caller should be passing you instead. Might be time for a rethink on why you want to do this, since trying to fight the system will only lead to pain.
I would suggest:
public static final String INTENTSENDER = "sender";
void mMethod() {
Intent intent = new Intent(context, mClass);
intent.putExtra(INTENTSENDER, mClass);
context.startActivity(intent);
}
knowing who sent it:
Class<?> c = (Class<?>)intent.getExtras().get(INTENTSENDER);
However, you can also use this:
ComponentName componentName = this.getCallingActivity();
Now, you can use componentName to get the sender of the intent.
Maybe it's best to use the extras parameters in the intent when you call them...like: Intent.putExtra(PARAM,value) on the caller activity...and on the opened activity you check:
intent.getStringExtra(PARAM)
getParentActivity() is not what yout are looking for?

Pass information from remote service to application

I created my own custom browser and I also have a background service that runs on startup. These are not in the same package, they are two separate installs. I want the service to be able to open my custom browser and launch a specific website in it at a specific time. I am currently able to launch the custom browser from the service but I don't know how to pass the specified url to it. Is this possible?
EDIT
I currently have it working now using something along the lines of this in my background service.
intent.putExtra("WebSite", "www.android.com")
then in my custom browser I put this in the onCreate() method
Intent sender = new Intent();
sender = getIntent();
String address = sender.getExtras().getString("WebSite");
I am getting the url then, but it is obviously force closing when I launch the app on my own instead of letting the remote service launch it because there is no intent for getIntent to get. I'm going to put a method in to check if there is an intent and if there is to launch it and if not skip. I think that should work. does anyone else have a better idea?
First activity (thus your service):
Intent myIntent = new Intent();
myIntent.putExtra("website", "www.android.com");
startActivity(myIntent);
Second activity (thus your browser:)
String website = "";
Bundle bundle = getIntent().getExtras();
if (bundle != null) {
website = bundle.getString("website");
}

Question regarding account creation and sync on Android

I've been reading the sample code from the dev docs on Android's site, specifically this:
http://developer.android.com/resources/samples/SampleSyncAdapter/src/com/example/android/samplesync/authenticator/AuthenticatorActivity.html
Which is the sole activity of the sample app. It refers to an intent in the onCreate method. I don't understand where this intent is coming from, or what it should contain if this is the only activity the app utilizes.
Log.i(TAG, "loading data from Intent");
final Intent intent = getIntent();
mUsername = intent.getStringExtra(PARAM_USERNAME);
mAuthtokenType = intent.getStringExtra(PARAM_AUTHTOKEN_TYPE);
mRequestNewAccount = mUsername == null;
mConfirmCredentials = intent.getBooleanExtra(PARAM_CONFIRM_CREDENTIALS, false);
That's the block of code working with the intent. Why would you have an intent for the only activity in the app? Is this app called in an unusual way? The Manifest does not include an intent filter for the activity... I guess I'm just a bit lost on this whole thing! If someone could set me straight that'd be great, thanks.
Why would you have an intent for the only activity in the app?
getIntent() gets you the intent that started this activity.
Is this app called in an unusual way?
I guess this activity is called programmatically from another app or activity, since it has been passed some extra data: getStringExtra() is used to extract some data from the intent that started it. putExtra.. and getExtra.. is a way to pass data between activities when they are started.
In that specific example, the intent is sent from the addAccount method in Authenticator.java. That method is called by the OS when you click the Add Account button in the Accounts & sync settings screen and choose your account type.

Categories

Resources