由于有米SDK 更新到 3.08 , 很多网上原有的教程已经不适用.ID和密码直接嵌入程序中, 不再在Manifest中注册, 用法上有很大的改变, 但同时也方便了很多.
还是官方的更新靠谱:
http://wiki.youmi.net/Youmi_Android_Banner_Version_3.08
SDK嵌入步骤
准备工作
步骤一.将 youmi-android.jar 导入您的工程中。
右键您的工程根目录,选择“New”,再选择“Folder”,输入Folder name为"libs"
将 youmi-android.jar 拷贝到工程根目录的libs文件夹下
右键 youmi-android.jar ,选择“Build Path”再选择“Add to Build Path”
导入成功
步骤二.在manifest.xml文件中配置用户权限
请务必配置以下权限,否则将有可能获取不到广告。
android.permission.INTERNET,连接网络权限 INTERNET ,用于请求广告
android.permission.READ_PHONE_STATE,用于精确统计用户手机的系统信息
android.ACCESS_NETWORK_STATE,用于精确识别网络接入点等信息
android.permission.ACCESS_COARSE_LOCATION,有助于精准投放地域广告以及帮助统计使用应用程序的用户的地区分布情况
android.permission.WRITE_EXTERNAL_STORAGE,有助于实现图片资源的缓存,节省流量,并可获得更好的用户体验
com.android.launcher.permission.INSTALL_SHORTCUT,用于支持一些新的广告形式
请将下面权限配置代码复制到 AndroidManifest.xml 文件中 :
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
<uses-permission android:name="android.permission.READ_PHONE_STATE"></uses-permission>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"></uses-permission>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"></uses-permission>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
<uses-permission android:name="com.android.launcher.permission.INSTALL_SHORTCUT"></uses-permission>
步骤三.在AndroidManifest.xml中添加AdActivity和YoumiReceiver
AdActivity是广告详情展示的载体,请在AndroidManifest.xml中添加AdActivity:
<activity android:name="net.youmi.android.AdActivity"
android:configChanges="keyboard|keyboardHidden|orientation"/>
YoumiReceiver是广告效果的接收器,请在AndroidManifest.xml中添加YoumiReceiver:
<receiver android:name="net.youmi.android.YoumiReceiver">
<intent-filter>
<action android:name="android.intent.action.PACKAGE_ADDED"/>
<action android:name="android.intent.action.PACKAGE_INSTALL"/>
<data android:scheme="package"/>
</intent-filter>
</receiver>
步骤四.初始化账号信息
在主Activity的onCreate中调用AdManager.init() 初始化 App ID 、App Secret、请求广告间隔和测试模式等参数(请务必在任意AdView初始化前调用一次)。
//第一个参数为您的应用发布Id
//第二个参数为您的应用密码
//第三个参数是请求广告的间隔,有效的设置值为30至200,单位为秒
//第四个参数是设置测试模式,设置为true时,可以获取测试广告,正式发布请设置此参数为false
AdManager.init(Context context,String appid, String appsec, int intervalSecond, boolean isTestMode);
!注意:3.04版本开始AdManager.init方法的参数改为五个,加上了Context参数
!请将测试模式设置为false后上传至网站等待审核。
!未上传应用安装包、未通过审核的应用、模拟器运行,都只能获得测试广告,审核通过后,模拟器上依旧是测试广告,真机才会获取到正常的广告。
步骤五.修改proguard.cfg
添加以下代码到proguard.cfg文件中
-keep class net.youmi.android.** {
*;
}
步骤六.设置发布渠道号【可选】
有米广告条 3.02版以后的sdk加入了分发渠道号设置,以后可以统计来自各个分发渠道的数据。
该设置为可选,当没有设置发布渠道号时,将采用默认渠道号0。
设置方法如下: 把以下代码复制到AndroidManifest.xml 文件中:
<meta-data android:name="YOUMI_CHANNEL" android:value="渠道编号"></meta-data>
注意:请在AndroidManifest.xml配置中加入meta-data参数,其中key为"YOUMI_CHANNEL" ,value为int型的渠道编号,请为每个不同渠道号打一个独立的包。详细的渠道编号请参见: http://wiki.youmi.net/wiki/PromotionChannelIDs
常用布局方式
使用xml布局嵌入广告
步骤一.在布局xml中设置广告条容器
以下为一个实例:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="@drawable/bg"
android:orientation="vertical" >
<!--adViewLayout为广告条容器-->
<LinearLayout
android:id="@+id/adViewLayout"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
>
</LinearLayout>
</LinearLayout>
步骤二.XML布局代码部分
public class XmlSample extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
// 应用Id 应用密码 广告请求间隔(s) 设置测试模式[false为发布模式]
AdManager.init(this,"XXXXXXXXXXXX", "XXXXXXXXXXXX", 30, false);
LinearLayout adViewLayout = (LinearLayout) findViewById(R.id.adViewLayout);
adViewLayout.addView(new AdView(this),
new LayoutParams(LinearLayout.LayoutParams.FILL_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));
}
}
使用代码布局嵌入广告
以下是一个示例
public class CodeSample extends Activity{
/** Called when the activity is first created. */
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
// 应用Id 应用密码 广告请求间隔(s) 设置测试模式[false为发布模式]
AdManager.init(this,"XXXXXXXXXXXX", "XXXXXXXXXXXX", 30, false);
LinearLayout layout=new LinearLayout(this);
layout.setOrientation(LinearLayout.VERTICAL);
layout.setBackgroundResource(R.drawable.bg);
//初始化广告视图,可以使用其他的构造函数设置广告视图的背景色、透明度及字体颜色
AdView adView = new AdView(this);
LayoutParams params = new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT);
layout.addView(adView, params);
setContentView(layout);
}
}
使用悬浮布局嵌入广告
以下是一个示例
public class SuspensoidSample extends Activity{
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
// 应用Id 应用密码 广告请求间隔(s) 设置测试模式[false为发布模式]
AdManager.init(this,"XXXXXXXXXXXX", "XXXXXXXXXXXX", 30, false);
setContentView(R.layout.main);
//初始化广告视图
AdView adView = new AdView(this);
FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.FILL_PARENT, FrameLayout.LayoutParams.WRAP_CONTENT);
//设置广告出现的位置(悬浮于屏幕右下角)
params.gravity=Gravity.BOTTOM|Gravity.RIGHT;
//将广告视图加入Activity中
addContentView(adView, params);
}
}
常见问题
版本更新内容
3.0版
全新的广告条界面。
重新定义广告条尺寸,详情请查看文档。
支持应用程序版本更新功能。
重新定义AdListener接口为AdViewListener,同时重命名其方法onReceiveAd为onAdViewSwitchedAd。并且修改了AdView的setAdListener(AdListener adListener)方法为setAdViewListener(AdViewListener listener)。详情请查看API文档。
为AdView类新增了一个方法:refreshAd()。调用该方法尝试刷新AdView展示的广告。在某些情况下,如想在一个停留时间极短的界面上快速地显示广告条,可以调用该方法尝试刷新广告,这样可以最大可能地避免出现这样的情况:一个只停留十几秒的界面由于广告没有及时出来而错过了展示广告的机会。详情请查看API文档
修改了AdManager类的init方法,取消了旧版本的appVersion参数,现在init方法只有4个参数。详情请查看API文档。
为AdManager新增了一个方法:disableUpdateApp。调用该方法可以取消使用应用程序版本更新功能。除非有特别需要,否则请不要调用此接口。详情请查看API文档
为AdManager新增了一个方法:setDonotClearWebViewCache。调用该方法设置SDK不删除所使用的WebView的缓存。除非有特别需要,否则请不要调用此接口。详情请查看API文档
修复了SDK内置网页浏览页在cmwap环境下出现乱码的一个bug。
该版本SDK兼容系统版本1.6及以上,对于1.5版本的系统可能有一定的兼容性问题。
3.01版
修复了3.0版导致混淆出错的bug。
修复了未成功请求广告时广告条占据广告位的bug。
轻量化了AdView的初始化流程,加快运行速度。
3.02版
加入了分发渠道号设置,以后可以通过后台统计来自各个分发渠道的数据。
修复了对android 1.5系统的兼容性问题。
3.03版
修复了文字广告有时候出现显示样式混乱的一个bug。
优化了请求广告线程的操作,减少资源消耗。
3.04版
在广告条的宽度设置为FILL_PARENT的情况下可自适应容器控件的宽度。
3.05版
优化了广告展示模式
3.07版
修复了初始化广告条设置setVisibility函数引起的bug
3.08版
修复了广告条被移除再添加显示不刷新的bug
新增弹出框展示广告的新特新
优化下载功能,提供断点续传下载
广告条的尺寸定义
新版本的SDK对广告条尺寸进行了调整:
使用LayoutParams进行广告条尺寸的设置
广告条的宽度必须设置为LayoutParams.FILL_PARENT或LayoutParams.WRAP_CONTENT,规则如下:
当宽度设置为LayoutParams.FILL_PARENT时,广告条的宽度为屏幕当前状态的宽度。如320*480的屏幕,当竖屏时,广告条宽度为320px;当横屏时,广告条宽度为480px。在v3.04以后,设置为该值时,广告条宽度与容器控件宽度一致
当宽度设置为LayoutParams.WRAP_CONTENT时,广告条的宽度为屏幕宽高中较小一边的值。如320*480的屏幕,无论屏幕的方向如何,广告条的宽度都为320px。
广告条的高度必须设置为LayoutParams.WRAP_CONTENT,并且广告条的高度会自动调整为50dp。
换算为px,则:
对于Low density (120), ldpi:
广告条的高度为38px;
对于Medium density (160), mdpi:
广告条的高度为50px;
对于High density (240), hdpi:
广告条的高度为75px;
对于Extra high density (320), xhdpi:
广告条的高度为100px;
有米广告Android SDK使用哪种字符编码
有米广告Android SDK使用UTF-8字符编码,在嵌入广告的时候请使用UTF-8编程环境,否则会出现乱码情况。
有米广告Android SDk兼容Android系统SDK的哪些版本
有米广告Android SDK兼容Android 系统 1.6及以上版本SDK,对于1.5及以下版本可能会有兼容性问题。
关于AdViewListener接口
当指定的AdView切换展示广告后或者请求广告失败后,该接口会通知监听者。 该接口的设计是为了方便那些有需要在广告条展示广告后进行一些界面处理的开发者,但它不适用于统计展示数, 因为在一个应用程序的生命周期中可能存在多个AdView实例,因此在运行的过程中,使用该接口统计到的切换展示广告的次数将会比广告的真正展示数多, 如果依据该接口来统计展示数,结果将会与真实展示数相差很大。查询详细的展示数据请登录有米平台: http://www.youmi.net
ps: 旧版本该接口的原型是AdListener,该接口的方法onReceiveAd实际上就是针对每个AdView实例切换广告的时候通知监听者, 作用与新接口一样,但其命名不准确,导致了一些不必要的误会,现更正其命名为 void onAdViewSwitchedAd(AdView adView) 。
关于广告没有成功展示的问题排查
如果出现广告没有展示的情况,请按下面的步骤检查:
检查广告配置是否正确,请务必仔细阅读并且按照"SDK嵌入步骤"中的"准备工作"一节中的步骤来完成广告的参数配置。如果该参数配置正确仍然无法显示广告,请按下一步检查。
使用Eclpse开发的朋友可以通过查看DDMS的logcat输出,有米广告的Tag是YoumiSdk。如果log信息中有输出Request Error Code,请将错误码发给有米客服。
关于混淆APK出错的问题
如果使用xml布局并且使用proguard混淆apk,请在proguard.cfg中加入以下代码:
-keep class net.youmi.android.** {
*;
}
更多常见问题
请查看 http://wiki.youmi.net
附录:API文档
net.youmi.android.AdManager
Class Overview
有米广告参数配置管理类,用于初始化请求广告的相关设置
Summary
Public Methods static void init(Context context,String appid, String appsec, int intervalSecond, boolean isTestMode) 初始化广告配置
static void setDonotClearWebViewCache() SDK在展示广告的过程中使用了WebView,如果您希望保留WebView的缓存,可以调用此接口设置SDK不删除WebView缓存。如无特别需要,请不要调用此接口。
static void disableUpdateApp() 新版SDK加入了应用版本检查更新功能,如果您不希望使用应用程序检查更新功能时,可以调用此接口关闭自动检查更新功能。如无特别需要,请不要调用此接口。
Public Methods
public static void init(Context context,String appid, String appsec, int intervalSecond, boolean isTestMode)
初始化广告参数,必须在任意AdView实例化前调用。建议仅且在应用启动的时候在主Activity的onCreate中调用该方法初始化一次。
参数:
context
appid - 应用Id
appsec - 应用密码
intervalSecond - 设置广告最小切换时间,单位为秒
isTestMode - 设置是否测试模式,如果设置为true,可以在真机上展示测试广告。在正式发布的版本中应该置为false
public static void setDonotClearWebViewCache()
SDK中有使用到WebView,为了避免应用程序中的缓存数据的积累造成大量的存储空间消耗,SDK会自动清除使用到的WebViewCache缓存。如果您的应用程序中有使用WebView,并且不希望清除缓存,可以调用此接口设置不清除缓存。否则,请不要调用此接口。
public static void disableUpdateApp()
有米广告Android 3.0版SDK加入了应用程序自动检查更新功能,这样可以很方便您的应用升级。以后当您升级应用程序的时候,只需要将应用程序的最新版本上传到我们的服务器,审核通过以后,您的旧版应用程序在启动的时候就会自动检查更新,在得到用户的授权后,应用程序会下载最新版本安装,这样老用户可以更快地使用最新版本的软件。 SDK默认开启应用程序检查更新功能 如果您不希望使用该功能,可以调用此接口停用该功能。
net.youmi.android.AdView
Class Overview
AdView是展示广告的载体
Summary
Public Constructors AdView(Activity activity) AdView构造函数,使用默认样式。
AdView(Context context, AttributeSet attrs) AdView构造函数,用于xml布局
AdView(Context context, AttributeSet attrs, int defStyle) AdView构造函数,用于xml布局
AdView(Activity activity, int backgroundColor, int textColor, int backgroundTransparent) AdView的构造函数
Public Methods int getAdWidth() 获取广告条宽度
int getAdHeight() 获取广告条高度
void refreshAd() 尝试刷新广告
void setAdViewListener(AdViewListener listener) 设置广告条监听接口
Public Constructors
public AdView(Activity activity)
AdView构造函数,使用默认样式
public AdView(Context context, AttributeSet attrs)
AdView构造函数,用于xml布局
public AdView(Context context, AttributeSet attrs, int defStyle)
AdView构造函数,用于xml布局
public AdView(Activity activity, int backgroundColor, int textColor, int backgroundTransparent)
AdView的构造函数
参数
activity - Activity
backgroundColor - 文字广告的背景颜色
textColor - 文字广告的字体颜色
backgroundTransparent - 文字广告的背景透明度,范围是0到255
Public Methods
public int getAdWidth()
获取广告条宽度
public int getAdHeight()
获取广告条的高度
public void refreshAd()
在某些情况下,如停留时间较短的页面上放置广告条,希望使广告条尽快地展示广告,可以调用此接口尝试刷新展示广告。
public void setAdViewListener(AdViewListener listener)
设置广告条监听接口
net.youmi.android.AdViewListener
Class Overview
AdView监听接口,监听一个指定的AdView的切换广告的状态。
Summary
Public Methods void onAdViewSwitchedAd(AdView adView) 当指定的AdView实例切换所展示的广告时,会调用此接口通知监听者
void onConnectFailed(AdView adView) 当指定的AdView实例请求广告失败时,如遇到手机网络断开等情况,会调用此接口通知监听者
Public Methods
public void onAdViewSwitchedAd(AdView adView)
当指定的AdView实例切换所展示的广告时,会通知此接口监听者。
该接口的设计是为了方便那些有需要在广告条展示广告后进行一些界面处理的开发者,但它不适用于统计展示数,因为在一个应用程序的生命周期中可能存在多个AdView实例,因此在运行的过程中,使用该接口统计到的切换展示广告的次数将会比广告的真正展示数多,如果依据该接口来统计展示数,结果将会与真实展示数相差很大。详细的展示数据请登录有米平台: http://www.youmi.net 查询。
ps: 旧版本该接口的原型是AdListener,该接口的方法onReceiveAd实际上就是针对每个AdView实例切换广告的时候通知监听者, 作用与新接口一样,但其命名不准确,导致了一些不必要的误会,现更正其命名为 void onAdViewSwitchedAd(AdView adView) 。
public void onConnectFailed(AdView adView)
当指定的AdView实例请求广告失败时,如遇到手机网络断开等情况,会调用此接口通知监听者
net.youmi.android.AdActivity
Class Overview
AdActivity是展示广告详情的载体,请在AndroidManifest.xml中添加AdActivity:
<activity android:name="net.youmi.android.spotad.AdActivity"
android:configChanges="keyboard|keyboardHidden|orientation"/>
net.youmi.android.YoumiReceiver
Class Overview
YoumiReceiver是广告效果的接收器,请在AndroidManifest.xml中添加YoumiReceiver:
<receiver android:name="net.youmi.android.YoumiReceiver">
<intent-filter>
<action android:name="android.intent.action.PACKAGE_ADDED"/>
<action android:name="android.intent.action.PACKAGE_INSTALL"/>
<data android:scheme="package"/>
</intent-filter>
</receiver>
另外, 如果要用ProGuard来加密的话, 不知是不是新版本的 android sdk 问题, 创建项目时没有传说中的 proguard.cfg 文件,而要自己手写!?
网上还是有好心的高人:
http://www.cnblogs.com/yyangblog/archive/2011/01/07/1929706.html
http://android.tgbus.com/Android/tutorial/201107/358743.shtml
完整的 proguard.cfg文件:
-optimizationpasses 5
-dontusemixedcaseclassnames
-dontskipnonpubliclibraryclasses
-dontpreverify
-verbose
-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*
-keep public class * extends android.app.Activity
-keep public class * extends android.app.Application
-keep public class * extends android.app.Service
-keep public class * extends android.content.BroadcastReceiver
-keep public class * extends android.content.ContentProvider
-keep public class com.android.vending.licensing.ILicensingService
-keepclasseswithmembernames class * {
native <methods>;
}
-keepclasseswithmembernames class * {
public <init>(android.content.Context, android.util.AttributeSet);
}
-keepclasseswithmembernames class * {
public <init>(android.content.Context, android.util.AttributeSet, int);
}
-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}
-keep class * implements android.os.Parcelable {
public static final android.os.Parcelable$Creator *;
}
一些实际开发的技巧:
1. 启动界面:
http://blog.sina.com.cn/s/blog_4d142b550100rs3f.html
2. 自适应屏幕密度:(写在 application 外, manifest 内)
<supports-screens android:smallScreens="true"
android:normalScreens="true"
android:largeScreens="true"
android:resizeable="true"
android:anyDensity="true" />
3. 强制屏幕不旋转, 输入法适应EditText位置:
<activity android:name=".subactivity.StrategyActivity"
android:screenOrientation="portrait"
android:windowSoftInputMode="adjustPan">
</activity>
4. 常用 permission(有米官方建议的 permissions):
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="com.android.launcher.permission.INSTALL_SHORTCUT"/>
原文来自Android SDK文档中的 docs/resources/articles/creating-input-method.html
编写输入法(IME)需要扩展 InputMethodService类。 这个类提供了输入法的基本实现,主要是管理输入法的状态和可见性以及与当前可见Activity的通信。
SDK中的SoftKeyboard是学习输入法的一个好例子。 可以修改这个示例代码来建立自己的输入法。
输入法打包成应用或服务, 跟其他应用类似。 在AndroidManifest.xml中, 声明输入法为一个Service, 包括适当的intent filter和其他的一些元信息。
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.fastinput"> <application android:label="@string/app_label"> <!-- Declares the input method service --> <service android:name="FastInputIME" android:label="@string/fast_input_label" android:permission="android.permission.BIND_INPUT_METHOD"> <intent-filter> <action android:name="android.view.InputMethod" /> </intent-filter> <meta-data android:name="android.view.im" android:resource="@xml/method" /> </service> <!-- Optional activities. A good idea to have some user settings. --> <activity android:name="FastInputIMESettings" android:label="@string/fast_input_settings"> <intent-filter> <action android:name="android.intent.action.MAIN"/> </intent-filter> </activity> </application> </manifest>
如果输入法允许用户进行某些设置, 需要提供一个用于设置的Activity。 这个Activity可以从Settings应用启动。 这里的Activity是可选的, 也可以直接在IME的UI里面直接提供用户设置。
InputMethodService典型的生命周期如下:
可视元素
输入法中有两个主要的可视元素, 输入视图和备选视图(原文:the input view and the candidates view)。 如果某个视图无关输入法的用户体验, 则不必按照这个风格。
输入视图
输入视图是用户可以输入文本的地方, 输入形式可以是按键、手写或手势。 当输入法第一次显示出来, InputMethodService.onCreateInputView()方法会被调用。 在该方法中创建并返回将要在输入法窗口中显示的View树结构。
备选视图
备选视图用于单词纠正,或者显示输入完成情况, 可供用户选择。 再次强调 , 这个备选视图可能与输入法相关也可能不相关, 如果不相关可以从InputMethodService.onCreateCandidatesView()返回null。 缺省情况该方法返回null。
设计不同的输入类型
可以指定应用的文本框类型, 比如可自由输入、数字、URL、邮箱或搜索。 实现一个新的输入法时, 需要意识到有不同的输入类型。 输入法不会自动在输入类型之间切换, 所以自定义的输入法需要支持所有的输入类型。 另外, IME不校验发送给应用的输入内容。 输入检验由应用自己完成。
比如, Android的LatinIME为文本输入和电话号码输入分别提供不同的布局:
InputMethodService.onStartInputView()方法接受一个EditorInfo对象作为参数, 该对象包含输入类型的具体细节以及the application's text field(???)的其他一些属性。
(EditorInfo.inputType & EditorInfo.TYPE_CLASS_MASK) 可以是下列某个值,
- TYPE_CLASS_NUMBER
- TYPE_CLASS_DATETIME
- TYPE_CLASS_PHONE
- TYPE_CLASS_TEXT
详细内容可参考android.text.InputType
EditorInfo.inputType还包含用于指示class variation(???)的掩码位和其他标志位。 比如, TYPE_TEXT_VARIATION_PASSWORD 或 TYPE_TEXT_VARIATIION_URI 或 TYPE_TEXT_FLAG_AUTO_COMPLETE.
密码域
当往密码框输入内容时需要注意, 应当保证密码在UI上不可见——不管是在输入视图还是备选视图。 并且, 不要在不明确提示用户的情况下保存密码。
风景模式和肖像模式
UI应该可以适应横屏和竖屏。 在非全屏输入法模式下, 留足够的空间让应用显示文本输入框以及相关的上下文内容。 更可取的方法是, IME不应用占用超过屏幕一半的空间。 全屏输入法不用考虑这个问题。
发送文本到应用
有两种方式从输入法发送文本到应用, 可以直接发送单个按键事件,或者编辑文本框中光标附近的文本。
构造KeyEvent对象并调用InputConnection.sendKeyEvent()即可发送按键事件到应用。 下面是一个例子:
InputConnection ic = getCurrentInputConnection(); long eventTime = SystemClock.uptimeMillis(); ic.sendKeyEvent(new KeyEvent(eventTime, eventTime, KeyEvent.ACTION_DOWN, keyEventCode, 0, 0, 0, 0, KeyEvent.FLAG_SOFT_KEYBOARD|KeyEvent.FLAG_KEEP_TOUCH_MODE)); ic.sendKeyEvent(new KeyEvent(SystemClock.uptimeMillis(), eventTime, KeyEvent.ACTION_UP, keyEventCode, 0, 0, 0, 0, KeyEvent.FLAG_SOFT_KEYBOARD|KeyEvent.FLAG_KEEP_TOUCH_MODE));
也可以使用以下方法
InputMethodService.sendDownUpKeyEvents(keyEventCode);
注意:建议某些输入框比如电话号码输入框使用第一种方法, 因为每次按键事件之后可能有过滤器应用于输入的文本。 对某些输入类型而言, 回车键和删除键也应当使用原始按键事件来发送(sent as raw key events), 因为应用可能正在监听特定的按键事件, 以便执行某些操作。
当编辑文本框中的文本时, 可使用android.view.inputmethod.InputConnection中的方法:
- getTextBeforeCursor()
- getTextAfterCursor()
- deleteSurroundingText()
- commitText()
比如, "Fell"位于输入光标的左边, 你想将它替换为"Hello!":
InputConnection ic = getCurrentInputConnection(); ic.deleteSurroundingText(4, 0); ic.commitText("Hello", 1); ic.commitText("!", 1);
提交前组合文本(Composing Text)
如果输入法进行文本预测或者需要多个步骤来组成一个单词或文字, 可以在文本输入框中显示这个过程, 直到用户提交整个单词。 这时可以使用完整的文本替换之前不完整的文本。 正在进行组合的文本可使用某种形式的高亮显示, 比如下划线。
InputConnection ic = getCurrentInputConnection(); ic.setComposingText("Composi", 1); ... ic.setComposingText("Composin", 1); ... ic.commitText("Composing ", 1);
尽管输入法窗口没有明确的获得焦点, 它仍然可以首先接收到实体按键事件,然后可以选择是否处理这些事件还是传递事件到应用。 比如, 组合文本过程时, 处理方向键事件,以在UI中导航到候选的单词(原文:you may want to consume the directional keys to navigate with your UI to candidate selection during composition)。 或者, 点击了Back键, 隐藏所有从输入法窗口中弹出来的菜单。 拦截实体按键事件需要重写InputMethodService.onKeyDown()和InputMethodService.onKeyUp()。 如果不想自己处理某个按键, 记住要调用 super.onKeyXXX()!
其他注意事项
- 提供便于用户直接从输入法界面打开相关设置界面的途径
- 提供便于用户从输入法界面上在不同输入法(设备上可能安装有多个输入法)之间切换的途径
- 快速显示界面——预加载或延迟加载大资源, 以便用户点击文本输入框时可以很快看到输入法界面。 缓存资源和视图, 加速下次调用输入法的过程
- 另一方面, 隐藏输入法窗口后尽早释放分配的大的内存块,以便应用有足够的内存。 当输入法进入隐藏状态时, 可以使用几秒的延迟消息来释放资源
- 确保输入法可输入最常用的字符, 比如用户可能在密码或用户名中输入标点, 要避免出现用户无法输入某个字符的情况而无法使用有密码保护的设备
例子
参考LatinIME的源码, 这是一个实际使用的输入法, 并且可支持文本预测及多种输入类型。 SDK中也包含一个SoftKeyboard例子。
Telnet协议是TCP/IP协议族中的一员,是Internet远程登陆服务的标准协议和主要方式。它为用户提供了在本地计算机上完成远程主机工作的能力。在终端使用者的电脑上使用telnet程序,用它连接到服务器。终端使用者可以在telnet程序中输入命令,这些命令会在服务器上运行,就像直接在服务器的控制台上输入一样。可以在本地就能控制服务器。
telnet服务位于busybox中。
[*] Support standalone telnetd (not inetd only)td only)
Login/Password Management Utilities --->
[ ] login //取消这选择
console #系统原文第一行
还有需要注意,pts/0表示可以同时开一个telnet端口登录,如果需要多个人同时登录,则需要多添加几个,比如:pts/1、pts/2等等。
[root@urbetter /]# telnet --help
BusyBox v1.13.3 (2009-03-25 15:48:45 CST) multi-call binary
Usage: telnet [-a] [-l USER] HOST [PORT]
Connect to telnet server
Options:
-a Automatic login with $USER variable
-l USER Automatic login as USER
2.开发板telnet登录到其他提供了telnet服务器的主机
---确认开发板的ip地址,确认开发板能连接Internet
ifconfig
ping 内网的ip ;ping 外网的ip
---设置路由ip:route add default gw 192.168.1.1
---登录:telnet 202.112.7.137
----------------------------------------------
3.开发板设置好网络,登录Internet
---设置网关:route add default gw 192.168.1.1(根据实际情况设定)
---确认连通Internet:ping 202.112.17.137
---设置域名解析服务器:
查看你pc机上的DNS服务器的ip地址 202.96.128.96
vim /etc/resolv.conf 添加 nameserver 202.96.128.96
或者rm /etc/resolv.conf ;touch /etc/resolv.conf;
echo nameserver 202.96.128.96 >> /etc/resolv.conf
-------------------------
4.开发板登录Linux主机
4.1Linux主机安装telnet服务
sudo apt-get install xinetd telnetd
修改配置
sudo vi /etc/inetd.conf并加入以下一行
telnet stream tcp nowait telnetd /usr/sbin/tcpd /usr/sbin/in.telnetd
4.2sudo vi /etc/xinetd.conf并加入以下内容:
# Simple configuration file for xinetd
#
# Some defaults, and include /etc/xinetd.d/
defaults
{
# Please note that you need a log_type line to be able to use log_on_success
# and log_on_failure. The default is the following :
# log_type = SYSLOG daemon info
instances = 60
log_type = SYSLOG authpriv
log_on_success = HOST PID
log_on_failure = HOST
cps = 25 30
}
includedir /etc/xinetd.d
----------------------------------------------
---------------------------------------------
4.3sudo vi /etc/xinetd.d/telnet并加入以下内容:
# default: on
# description: The telnet server serves telnet sessions; it uses
# unencrypted username/password pairs for authentication.
service telnet
{
disable = no
flags = REUSE
socket_type = stream
wait = no
user = root
server = /usr/sbin/in.telnetd
log_on_failure += USERID
}
5. 重启机器或重启网络服务sudo /etc/init.d/xinetd restart
6. 使用TELNET客户端远程登录;
ifconfig -a 显示本机地址。