Getting Started with Android Studio Plugin Development

Reprinted from: http://blog.csdn.net/qq_27258799 https://blog.csdn.net/qq_27258799/article/details/78093734

foreword

This article is an introduction to AS plug-in development. It aims to understand the entire development process, and the code is relatively rough.

AS plug-ins are definitely a powerful tool on our development road. Here are a few plug-ins that I commonly use.

Json to Java class

Quickly generate findViewById code

CodeGlance

write picture description here

Preparation before development

If a worker wants to do a good job, he must first sharpen his tools. First of all, we have to prepare the IDE, here we use  Intellij , the Community version I downloaded.

After the installation is complete, create a new plugin development project:

write picture description here

About project SDK, to say something. If not sdk, just click Newand select the one that comes with the software, but there may be a prompt here that it is not available Java jdk. On your own machine, just find a version jdk, I use 1.8.

The newly created project directory is as follows:

write picture description here

Next, we imitate ECTranslation to write a translation plug-in, because the principle is simple, easy to use, and easy to implement. If you understand the principle, you can make one yourself.

Because the API of Youdao Translation is to be used, we need to register the developer on Youdao Zhiyun first, apply for the natural language translation service after registration, and create an application.

write picture description here

The process of requesting the API, Youdao Translation has prepared a Demo for us

I directly posted the request process in Java:

public class Demo {

    public static void main(String[] args) throws Exception {
        String appKey ="您的appKey";
        String query = "good";
        String salt = String.valueOf(System.currentTimeMillis());
        String from = "EN";
        String to = "zh-CHS";
        String sign = md5(appKey + query + salt+ "您的密钥");
        Map params = new HashMap();
        params.put("q", query);
        params.put("from", from);
        params.put("to", to);
        params.put("sign", sign);
        params.put("salt", salt);
        params.put("appKey", appKey);
        System.out.println(requestForHttp("https://openapi.youdao.com/api", params));
    }

    public static String requestForHttp(String url,Map requestParams) throws Exception{
        String result = null;
        CloseableHttpClient httpClient = HttpClients.createDefault();
        /**HttpPost*/
        HttpPost httpPost = new HttpPost(url);
        List params = new ArrayList();
        Iterator> it = requestParams.entrySet().iterator();
        while (it.hasNext()) {
            Entry en = it.next();
            String key = en.getKey();
            String value = en.getValue();
            if (value != null) {
                params.add(new BasicNameValuePair(key, value));
            }
        }
        httpPost.setEntity(new UrlEncodedFormEntity(params,"UTF-8"));
        /**HttpResponse*/
        CloseableHttpResponse httpResponse = httpClient.execute(httpPost);
        try{
            HttpEntity httpEntity = httpResponse.getEntity();
            result = EntityUtils.toString(httpEntity, "utf-8");
            EntityUtils.consume(httpEntity);
        }finally{
            try{
                if(httpResponse!=null){
                    httpResponse.close();
                }
            }catch(IOException e){
                e.printStackTrace();
            }
        }
        return result;
    }

    /**
     * 生成32位MD5摘要
     * @param string
     * @return
     */
    public static String md5(String string) {
        if(string == null){
            return null;
        }
        char hexDigits[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
                'A', 'B', 'C', 'D', 'E', 'F'};

        try{
            byte[] btInput = string.getBytes("utf-8");
            /** 获得MD5摘要算法的 MessageDigest 对象 */
            MessageDigest mdInst = MessageDigest.getInstance("MD5");
            /** 使用指定的字节更新摘要 */
            mdInst.update(btInput);
            /** 获得密文 */
            byte[] md = mdInst.digest();
            /** 把密文转换成十六进制的字符串形式 */
            int j = md.length;
            char str[] = new char[j * 2];
            int k = 0;
            for (byte byte0 : md) {
                str[k++] = hexDigits[byte0 >>> 4 & 0xf];
                str[k++] = hexDigits[byte0 & 0xf];
            }
            return new String(str);
        }catch(NoSuchAlgorithmException | UnsupportedEncodingException e){
            return null;
        }
    }

    /**
     * 根据api地址和参数生成请求URL
     * @param url
     * @param params
     * @return
     */
    public static String getUrlWithQueryString(String url, Map params) {
        if (params == null) {
            return url;
        }

        StringBuilder builder = new StringBuilder(url);
        if (url.contains("?")) {
            builder.append("&");
        } else {
            builder.append("?");
        }

        int i = 0;
        for (String key : params.keySet()) {
            String value = params.get(key);
            if (value == null) { // 过滤空的key
                continue;
            }

            if (i != 0) {
                builder.append('&');
            }

            builder.append(key);
            builder.append('=');
            builder.append(encode(value));

            i++;
        }

        return builder.toString();
    }
    /**
     * 进行URL编码
     * @param input
     * @return
     */
    public static String encode(String input) {
        if (input == null) {
            return "";
        }

        try {
            return URLEncoder.encode(input, "utf-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }

        return input;
    }
}

Before development, let's talk about the principle of translation. The entire translation process is very simple. Get the word selected by the mouse, call the translation API, organize the translation results and display them.

The API of Youdao Translation is used here. The new version of Youdao Zhiyun's natural language translation API is no longer free, but users will receive a 100-yuan experience fee after registration. The charging standards are as follows:

write picture description here

If it is for our own personal use, 100 yuan is enough for us to toss.

Then enter the formal development process.

Plug-in development process

First create a new Action file:

write picture description here

Then fill in the Action ID, Class Name, and shortcut keys:

write picture description here 
In the picture above, we put the newly added translation button under Editthe command, the name of the command is translation, and the shortcut key is Alt+E.

After confirming, take a plugin.xmllook this piece of code:


  <actions>
    <action id="zttranslation" class="ZTTranslation" text="Translation" description="translate word" icon="/icons/ic_logo.png">
      <add-to-group group-id="EditMenu" anchor="first"/>
      <keyboard-shortcut keymap="$default" first-keystroke="alt E"/>
    </action>
  </actions>

This is the configuration file corresponding to our newly created translation Action. To expand here, in the above configuration file, I added an icon to my Action, like this: 
write picture description here

We can create a new icons directory in the resources directory and add an icon image (suffixed with)

write picture description here

Then add the corresponding configuration in the configuration file: icon="/icons/ic_logo.png"·. When the AS theme becomes black, the Action's logo will automatically use the logo with the suffix dark.

Let's take a look at the newly created ZTTranslationclass:

public class ZTTranslation extends AnAction {

    @Override
    public void actionPerformed(AnActionEvent e) {
        // TODO: insert action logic here
    }

}

Next we need to get the word selected by the mouse and display it in a pop-up box:

public class ZTTranslation extends AnAction {

    @Override
    public void actionPerformed(AnActionEvent e) {
        final Editor mEditor = e.getData(PlatformDataKeys.EDITOR);
        if (null == mEditor) {
            return;
        }
        SelectionModel model = mEditor.getSelectionModel();
        final String selectionTxt = model.getSelectedText();
        if (TextUtils.isEmpty(selectionTxt)) {
            return;
        }
         Messages.showMessageDialog(selectionTxt,"TestWord",Messages.getInformationIcon());
    }

}

Run it to see the effect.

After running, a new window will be re-opened, and a new project will be created casually. Look at the Edit command:

write picture description here

We created a new one Translationon the first line. Under the test below, select the word:

write picture description here

Everything is normal, then we continue to access the translation.

 @Override
    public void actionPerformed(AnActionEvent e) {
        final Editor mEditor = e.getData(PlatformDataKeys.EDITOR);
        if (null == mEditor) {
            return;
        }
        SelectionModel model = mEditor.getSelectionModel();
        final String selectionTxt = model.getSelectedText();
        if (TextUtils.isEmpty(selectionTxt)) {
            return;
        }
        //调用有道翻译Demo
        String result = HttpUtils.findTranslation(selectionTxt);
        StringBuilder sb = buildResult(result);
        String translation;
        if (sb.length() == 0) {
            translation = "暂无此翻译!";
        } else {
            translation = sb.toString();
        }
        showTranslationPopup(mEditor, translation);
    }

HttpUtils.findTranslation(selectionTxt)It is the request Demo on the Youdao official website that I posted above, and then rearrange the returned string according to the design idea. The returned result of the translation request is as follows:

{
  "errorCode":"0",
  "query":"good", //查询正确时,一定存在
  "translation": [ //查询正确时一定存在
      "好"
  ],
  "basic":{ // 有道词典-基本词典,查词时才有
      "phonetic":"gʊd"
      "uk-phonetic":"gʊd" //英式发音
      "us-phonetic":"ɡʊd" //美式发音
      "explains":[
          "好处",
          "好的"
          "好"
      ]
  },
  "web":[ // 有道词典-网络释义,该结果不一定存在
      {
          "key":"good",
          "value":["良好","善","美好"]
      },
      {...}
  ]
  ],
  "dict":{
      "url":"yddict://m.youdao.com/dict?le=eng&q=good"
  },
  "webdict":{
      "url":"http://m.youdao.com/dict?le=eng&q=good"
  },
  "l":"EN2zh-CHS"
}

I only take the translation result of "explains" here, and then pop up a popup to show:

 private void showTranslationPopup(final Editor editor, final String result) {
        ApplicationManager.getApplication().invokeLater(new Runnable() {
            @Override
            public void run() {
                JBPopupFactory factory = JBPopupFactory.getInstance();
                factory.createHtmlTextBalloonBuilder(result, null, new JBColor(new Color(186, 238, 186), new Color
                        (73, 117, 73)), null).setFadeoutTime(5000).createBalloon().show(factory
                        .guessBestPopupLocation(editor), Balloon.Position.below);
            }
        });
    }

Then run it again to see, English to Chinese:

write picture description here

Chinese to English:

write picture description here

This is just an example of an exercise, so no more details are considered, but it is still very powerful to look at the source code to deal with uncommon words in the future, haha.

The last thing is to compile and export the plugin package and run it to our Android Studio.

write picture description here

write picture description here

The plug-in zip package is exported to the project path, and then we quickly open the AS to install the plug-in and try.

write picture description here

After the installation is complete, restart AS on it.

write picture description here

Publishing process

Plugin information configuration

Now that we have the plugin ready, if more people search for it, we have to publish it to the plugin repository. Let's take a look at the publishing process.

First we need to complete the plugin information: 
write picture description here

The default configuration file looks like this:

<idea-plugin version="2">
  <id>com.your.company.unique.plugin.id</id><!--插件ID,自定义,如果要上传到Plugins仓库不能有重复ID -->
  <name>Plugin display name here</name><!--插件名称-->
  <version>1.0</version>
  <vendor email="[email protected]" url="http://www.yourcompany.com">YourCompany</vendor><!--邮箱和网址,上传到Plugins仓库会在你的插件界面显示 -->

  <!-- 你的插件的简介,同样是显示在Plugins仓库信息界面 -->
  <description><![CDATA[
      Enter short description for your plugin here.<br>
      <em>most HTML tags may be used</em>
    ]]></description>

  <!-- 版本更新信息-->
  <change-notes><![CDATA[
      Add change notes here.<br>
      <em>most HTML tags may be used</em>
    ]]>
  </change-notes>

  <!-- please see http://www.jetbrains.org/intellij/sdk/docs/basics/getting_started/build_number_ranges.html for description -->
  <idea-version since-build="141.0"/>

<!--产品选择,下文详细说明 -->
  <!-- please see http://www.jetbrains.org/intellij/sdk/docs/basics/getting_started/plugin_compatibility.html
       on how to target different products -->
  <!-- uncomment to enable plugin in all products
  <depends>com.intellij.modules.lang</depends>
  -->

<!--扩展组件注册 要是用到applicationConfigurable即项目配置等就在这里注册-->
  <extensions defaultExtensionNs="com.intellij">
    <!-- Add your extensions here -->
  </extensions>

<!--Action注册,这里的代码会根据我们最开始New Action时所填信息自动生成 -->
  <actions>
    <!-- Add your actions here -->
  </actions>

</idea-plugin>

We need to fill in some key information, which  descriptionmust be in English , otherwise it will be called back by the official after submitting it to the market. descriptionSupport html tags, those who are unfamiliar can use the online Html editor directly .

Also note this:

  <!-- please see http://www.jetbrains.org/intellij/sdk/docs/basics/getting_started/plugin_compatibility.html
       on how to target different products -->
  <!-- uncomment to enable plugin in all products
  <depends>com.intellij.modules.lang</depends>
  -->

Here is the product type that configures your plugin to publish to the jetbrains plugin repository.

We all know that jetbrains has many products, such as our commonly used Android Studio, Intellij, etc., which all support plug-ins.

If we comment the above code, our plug-in will be uploaded to the Intellij repository by default, which means that others can only search for our plug-in in Intellij, but cannot find it in AS... So we remove the comment and we can default Upload to all repositories.

After configuring the information, we need to recompile and generate the plugin.

Register Jetbrains warehouse account

After preparing the plugin information, we need to register the repository account: Jetbrains Plugins Repository

write picture description here

After uploading, an official review is required, and then feedback information will be sent to our registered email address. If our configuration file format is incorrect, for example, if I used a Chinese description at the beginning, it will be rejected by the market...

If everything is normal, you will receive an official congratulation email in one or two working days~ Then we can search it in the warehouse.

write picture description here

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324609451&siteId=291194637