When developing Android applications, you often have to resort to using adb to optimize your work and save time. Adb is the only tool that allows, for example, bypassing the long chain of activity and launching the desired message immediately or sending a broadcast message without waiting for the fulfillment of any external conditions. Using adb entails all the inconvenience of using the terminal to form long commands, which led me to write a plugin to speed up and simplify working with adb when sending intent to devices.
Finding information and detailed descriptions of how to develop a plugin for IntelliJ IDEA is not a problem, so at the end of the article I will devote a few paragraphs to this topic, showing the features that I encountered. Now I want to describe the result of my work.
So,
Android Intent Sender is tied to the following adb shell commands:
- Broadcast - using the command allows you to send broadcast messages to the client
- StartActivity - starting the activity
- StartService - start the service
When sending these commands, you can attach an intent supplied with all the necessary parameters (action, data, category, component, mime type, flag) and extra data.
')
The appearance of the plug-in was decided to be in the form of a separate working window with the necessary UI elements. Access to the plugin is carried out through the menu View -> Tool Windows, the icon on the left-bottom of the screen and from the right panel:

The plugin window is divided into the following main sections: device / emulator selection window, intent parameters section, command sending buttons. The plugin implements automatic updating of devices when they are connected and disconnected. In the intent parameters section, in addition to the input fields, there is a history button (to the right of the section title), a picker of the current project’s classes next to the component entry field, a picker of flags and an extra data button.
The class picker of the current project greatly simplifies the selection of a component (for example, a running activity). Clicking on the button opens a window with project classes with the ability to search and switch to the project tree. When you select a class, the required separator “/” for the package border (for example, com.weezlabs.blabla / .MainActivity) will be automatically inserted in the right place:

The flags picker allows you to select one or more flags to add to the intent:

To send a command to the device, use the buttons
“Send Broadcast” ,
“Start Activity” ,
“Start Service” .
To launch activity and service via adb, it is generally necessary that the manifest for this component have the
android:exported=”true”
flag in it
android:exported=”true”
. However, as it turned out, there is a solution that allows you to start a component whose exported flag is set to false. For this, the
“Add user” field has been added to the plugin, in which the package id is automatically substituted when selecting a component from the piker. Unfortunately, this functionality may not work on some devices (it seems that this applies to most Samsung devices).
Consider some cases of possible use of the plugin:
Testing broadcast receiverEverything is simple: we specify the necessary parameters and send intent. For example, we have a receiver with the code in onReceive:
@Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); if (action.equals("simple_intent_action")){ Log.d("SimpleReceiver", "Got intent with action: " + action + " and string extra: " + intent.getStringExtra("string_extra")); } }
Receiver is registered by specifying the corresponding IntentFilter:
IntentFilter simpleFilter = new IntentFilter("simple_intent_action");
Then, in order to send a broadcast message in the plugin in the action field, we specify
“simple_intent_action” and, by clicking on the
“Add extra” button, we add extra with the key
“string_extra” and any text. Click
“Send Broadcast” and see something in the logs, like:
Got intent with action: simple_intent_action and string extra: Awesome string
Running an activity, serviceSuppose we need to start the MessageActivity, while the MessageActivity during creation takes the id of the displayed message of type long from the intent. The key in the extra data for id let it be “messageId”.
To run this activation in the plugin in the component picker, select MessageActivity, and make sure that the user is automatically added. Next, add an extra object of type
long with the key
“messageId” and the desired value. Everything is ready, click
“Start Activity” and look at the started activity with the display of the specified message.
If MessageActivity in the onCreate method writes logs:
Log.d(LOG_TAG, "Message id: " + getIntent().getLongExtra("messageId", -1));
then we will see in the logs:
Message data: 234
Testing your own data schemaFor example, we need to implement the automatic launch of the application by clicking on certain links, like
myhost.com...
/ To do this in manifest, we specify the following intent filter for the desired activity:
<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="http" android:host="myhost.com"/> </intent-filter>
In the onCreate method of the called activity add logging:
Log.d("TAG", "Intent data: " + getIntent().getDataString());
Then, for testing, in the plugin we specify the action:
android.intent.action.VIEW , data:
myhost.com/some_data and click
Start Activity . On the device, select our application and look at the logs:
Intent data: myhost.com/some_data
We will see the same thing if we send yourself an sms with the text “Test
myhost.com/some_data ” and click on the link
Testing Google Cloud Messaging (GCM) serviceSuppose we have a class GcmBroadcastReceiver which is responsible for receiving GCM messages. Registration of such components in manifest takes place with the indication for the receiver of the permission
android:permission="com.google.android.c2dm.permission.SEND"
android:permission="com.google.android.c2dm.permission.SEND"
.
Unfortunately, at the time of testing, this permission must be removed, otherwise the intent from the plugin will not be processed. The filter in manifest will be similar to the following:
<intent-filter> <action android:name="com.google.android.c2dm.intent.RECEIVE" /> <category android:name="com.your.package" /> </intent-filter>
Suppose that in the body of the GCM intent we expect json with some data, transmitted by the string with the key
“message” .
We create intent in the plugin, for which we specify the action
com.google.android.c2dm.intent.RECEIVE and the category
com.your.package . Add an extra field of type
String with the key
“message_type” and the value of
“gcm” and a field of type
String with the key
“message” and transmitted by json inside.
Now, by clicking
“Send broadcast” , the application will receive and process the broadcast, as it would process the real GCM message.
As can be seen, in some cases, the use of a plug-in can significantly reduce unreasonable loss of time and, I hope, the plug-in will become a really useful tool in the developer’s arsenal.
Regarding the plugin development process itself, I can say that the complexity is determined by the complexity of the implementation of the idea embedded in the plugin. Preparation and setting up the environment itself does not cause problems, there is a lot of information on the Internet. I will give in brief the necessary steps to set up the environment:
- We are looking for the IDEA branch used for AndroidStudio. To do this, look for the line in AndroidStudioApplicationInfo.xml, similar to apiVersion = "135.1286" and pick up the branch number from it - in my case 135. AndroidStudioApplicationInfo.xml we look at the link: android.googlesource.com/platform/tools/adt/idea/+/ idea133 / adt-branding / src / idea / AndroidStudioApplicationInfo.xml
Naturally, the link is not strictly recommended and you can go to the desired version of AndroidStudio, cutting the link to android.googlesource.com/platform/tools/adt/idea and then, by walking through the folders, you can easily find the desired AndroidStudioApplicationInfo.xml - Download IntelliJ Community Edition as described and switch to the branch found earlier (I have 135)
- Create an SDK for plugin development
- The penultimate step: add to the SDK in the classpath section of the android plugin dependencies:

- Add org.jetbrains.android dependency to
org.jetbrains.android
org.jetbrains.android
Next, create a new project like IntelliJ Platform Plugin and you can safely start writing a plugin using the
IntelliJ Platform SDK Documentation ,
Open API and Plugin Development community , numerous articles on Habré and examples on github.
I decided to implement the plugin based on the toolWindow component using the swing framework for the UI elements. As a person who has never encountered working with UI in Java and with swing in particular, had to adapt slightly to its features, however, there were no particular difficulties. Perhaps the similarity with the work on the UI in Android helped.
Additionally, I note that for working with adb, the ddmlib library, which is part of the Android SDK and located along the path
$ {SDK_HOME} / sdk / tools / lib , turned out to be extremely useful. There are quite a lot of other jar-s in this directory, so I recommend viewing, all of a sudden some library will simplify the solution of the tasks. I also draw attention to the
org.jetbrains.android package, which greatly helps when working with the Android part. So, with his help, the path to the Android SDK directory was obtained and the package was pulled out of the manifest. Just in case, the plugin also provides the search for the path to the Android SDK in the ANDROID_HOME environment variable and the ability to manually set the path if it was not possible to find the SDK in the previous steps. When working with adb, the plugin parses the console response, which makes it possible in some cases to understand that the sending failed and give the corresponding error.
To store the history of commands used json, stored in the settings of the plugin.
In connection with the development of a plug-in in a Windows environment, when it was launched on OS X, a number of
crashes occurred with a
NoSuchMethodException . The reason is the difference between Java for Windows and OS X. I had to disturb my colleagues working on OS X and debug it with their help.
After completion of testing and debugging the plug-in, an application was submitted to add it to the jetbrains plugin repository. The first submitted version was quickly moderated and was available for download no more than an hour after the application was submitted.
Conclusion:
To my surprise, the writing of the plugin did not cause any significant technical difficulties. Perhaps, the desire to make an open useful tool, switching from Android development or just inspired, helped, but somehow the development of the plug gave a good moral shake and charged for some time with an additional positive attitude. Although the plugin is already self-sufficient and fully functional, work on the plugin is not yet completed, there is something to improve and there are ideas for other useful plug-ins. Todo sheet for the plugin:
- Add the ability to initiate the assembly and run the project with the indication of the activity being started and its parameters
- Try to bypass the temporary removal of permission from the GCM receiver
- Implement support for passing intent Parcelable objects.
- Solve the problem of running non-exported components on Samsung devices
Plugin on
github :
github.com/WeezLabs/idea-intent-sender-pluginAs a bug tracker, you can safely use
github issues :
github.com/WeezLabs/idea-intent-sender-plugin/issues .
I would welcome any suggestions for improving the plugin or questions on its implementation, as well as updating the list of non-obvious ways to use it.