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.
Quickly generate findViewById code
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:
About project SDK
, to say something. If not sdk
, just click New
and 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:
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.
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:
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:
Then fill in the Action ID, Class Name, and shortcut keys:
In the picture above, we put the newly added translation button under Edit
the command, the name of the command is translation
, and the shortcut key is Alt+E
.
After confirming, take a plugin.xml
look 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:
We can create a new icons directory in the resources directory and add an icon image (suffixed with)
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 ZTTranslation
class:
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:
We created a new one Translation
on the first line. Under the test below, select the word:
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:
Chinese to English:
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.
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.
After the installation is complete, restart AS on it.
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:
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 description
must be in English , otherwise it will be called back by the official after submitting it to the market. description
Support 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
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.