十年网站开发经验 + 多家企业客户 + 靠谱的建站团队
量身定制 + 运营维护+专业推广+无忧售后,网站问题一站解决
需要在资源文件中添加一个button,然后如果你需要给这个button增加点击事件,那你就需要在代码中找到这个button,给它添加点击事件监听,在监听中响应你所需要的完成的操作。
十年的阆中网站建设经验,针对设计、前端、开发、售后、文案、推广等六对一服务,响应快,48小时及时工作处理。全网营销推广的优势是能够根据用户设备显示端的尺寸不同,自动调整阆中建站的显示方式,使网站能够适用不同显示终端,在浏览器中调整网站的宽度,无论在任何一种浏览器上浏览网站,都能展现优雅布局与设计,从而大程度地提升浏览体验。创新互联从事“阆中网站设计”,“阆中网站推广”以来,每个客户项目都认真落实执行。
Android系统手机添加桌面图标可以进入菜单界面找到想要建立桌面快捷方式的程序,按住图标不放,感到一下震动之后,图标即可移动,然后把图标拖动到您想要摆放的位置就可以松手了(注意操作期间要按定图标不要放)。(上述内容仅适用于广东联通用户)
在AndroidManifest中添加android:name
新建android:name对应的class,并定义public方法继承Application
在android中添加系统服务,下面以SurfaceComposer这个service为例,
① 首先提供接口文件ISurfaceComposer.h
//frameworks\native\include\gui\ISurfaceComposer.h
//首先是接口,c++实现是虚函数
class ISurfaceComposer: public IInterface {
public:
DECLARE_META_INTERFACE(SurfaceComposer);
// flags for setTransactionState()
enum {
eSynchronous = 0x01,
eAnimation = 0x02,
};
enum {
eDisplayIdMain = 0,
};
/* create connection with surface flinger, requires
* ACCESS_SURFACE_FLINGER permission
*/
virtual spISurfaceComposerClient createConnection() = 0;
}
② 建立BnSurfaceComposer
建立BnSurfaceComposer,需要重写BBinder的onTransact函数。
class BnSurfaceComposer: public BnInterfaceISurfaceComposer {
public:
enum {
// Note: BOOT_FINISHED must remain this value, it is called from
// Java by ActivityManagerService.
BOOT_FINISHED = IBinder::FIRST_CALL_TRANSACTION,
CREATE_CONNECTION,
CREATE_GRAPHIC_BUFFER_ALLOC,
CREATE_DISPLAY_EVENT_CONNECTION,
CREATE_DISPLAY,
DESTROY_DISPLAY,
GET_BUILT_IN_DISPLAY,
SET_TRANSACTION_STATE,
AUTHENTICATE_SURFACE,
BLANK,
UNBLANK,
GET_DISPLAY_INFO,
CONNECT_DISPLAY,
CAPTURE_SCREEN,
};
virtual status_t onTransact(uint32_t code, const Parcel data,
Parcel* reply, uint32_t flags = 0);
};
③ Bpxxx的实现
frameworks\native\libs\gui\ISurfaceComposer.cpp中,
//Bp实现,代理端
class BpSurfaceComposer : public BpInterfaceISurfaceComposer
{
public:
BpSurfaceComposer(const spIBinder impl)
: BpInterfaceISurfaceComposer(impl)
{
}
//代理接口
virtual spISurfaceComposerClient createConnection()
{
uint32_t n;
Parcel data, reply;
data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
remote()-transact(BnSurfaceComposer::CREATE_CONNECTION, data, reply);
return interface_castISurfaceComposerClient(reply.readStrongBinder());
}
}
④ Bnxxx的实现
//Bn端,即server端
status_t BnSurfaceComposer::onTransact(
uint32_t code, const Parcel data, Parcel* reply, uint32_t flags)
{
switch(code) {
case CREATE_CONNECTION: {
CHECK_INTERFACE(ISurfaceComposer, data, reply);
//createConnection就是server端的实现函数
spIBinder b = createConnection()-asBinder();
reply-writeStrongBinder(b);
return NO_ERROR;
}
default: {
return BBinder::onTransact(code, data, reply, flags);
}
}
// should be unreachable
return NO_ERROR;
}
⑤ 注册service
通过上面几步已经完成了service的建立,我们需要将service注册到service manager中。
class SurfaceFlinger : public BnSurfaceComposer,
//在frameworks\native\services\surfaceflinger\main_surfaceflinger.cpp中,
// publish surface flinger
spIServiceManager sm(defaultServiceManager());
sm-addService(String16(SurfaceFlinger::getServiceName()), flinger, false);
⑥ 使用service
//首先获取代理端BpSurfaceComposer
spISurfaceComposer composer(ComposerService::getComposerService());
//直接调用代理BpSurfaceComposer的接口
spIGraphicBufferAlloc alloc(composer-createGraphicBufferAlloc());
其中getComposerService()的实现为,
/*static*/ spISurfaceComposer ComposerService::getComposerService() {
ComposerService instance = ComposerService::getInstance();
Mutex::Autolock _l(instance.mLock);
if (instance.mComposerService == NULL) {
ComposerService::getInstance().connectLocked();
assert(instance.mComposerService != NULL);
ALOGD("ComposerService reconnected");
}
return instance.mComposerService;
}
void ComposerService::connectLocked() {
const String16 name("SurfaceFlinger");
//获取service,返回的mComposerService是BpSurfaceComposer,有了Bp就能直接调用代理接口了
while (getService(name, mComposerService) != NO_ERROR) {
usleep(250000);
}
assert(mComposerService != NULL);
// Create the death listener.
class DeathObserver : public IBinder::DeathRecipient {
ComposerService mComposerService;
virtual void binderDied(const wpIBinder who) {
ALOGW("ComposerService remote (surfaceflinger) died [%p]",
who.unsafe_get());
mComposerService.composerServiceDied();
}
public:
DeathObserver(ComposerService mgr) : mComposerService(mgr) { }
};
mDeathObserver = new DeathObserver(*const_castComposerService*(this));
mComposerService-asBinder()-linkToDeath(mDeathObserver);
}
java添加service
Android为了方便开发人员,提供了AIDL工具,简化了编写service的难度。下面以添加TestService这个服务为例,
① 编写AIDL文件
package android.app;
interface ITestService {
boolean enableWifi(boolean enabled);
}
TestService的AIDL文件提供了一个接口,enableWifi()。
② 创建TestService服务
TestService 服务需要继承ITestService.Stub类,这个类就是通过AIDL工具对①中的AIDL文件处理后产生的,
class TestService extends ITestService.Stub {
//实现接口
public boolean enableWifi(boolean enabled)
{
......
}
}
③ Context.java中添加service名字字符串
// Context.java中添加service名字字符串
public static final String TEST_SERVICE = "my_test";
④ 向ServiceManager中注册service
java中大部分的系统service都是在SystemServer中去向service manager注册的,
//ServiceManager注册service
// 在SystemServer.java中,模仿其他向ServiceManager添加service的方法
try {
TestService myService = new TestService(context);
ServiceManager.addService(Context.TEST_SERVICE, myService);
} catch (Throwable e) {
reportWtf("register my test service fail", e);
}
⑤创建服务对应的Manager
对于每一个service而言,通常会有一个相关的Manager。 Managers提供API给app使用,成为SDK的一部分,是apps和remote service的中间桥梁。Manager中的接口和Service中的接口必须一一对应。
public class TestServiceManager{
private final ITestService mService;
private final Context mContext;
//构造函数中传入的service,其实就是BpTestService
TestServiceManager(Context context,ITestService service) {
mContext = context;
mService = service;
}
public boolean enableWifi(boolean enabled) {
try {
return mService.enableWifi(enabled);
} catch (RemoteException ex) {
}
return false;
}
}
到目前为止,我们只是完成了Service的注册,但是还没有使用,该如何使用?
⑥ contextImpl中注册Manager
一旦我们实现了service和对应的Manager,需要有一种方法在app中调用他们。前面说过,Manager会成为SDK的一部分,供我们调用,那么Manager和Service是如何联系起来的?首先需要将我们的service和mangager注册到execution context,即contextImpl中,
registerService(TEST_SERVICE, new ServiceFetcher() {
public Object createService(ContextImpl ctx) {
IBinder b = ServiceManager.getService(TEST_SERVICE);
//asInterface(BpBinder)后就是BpTestService
ITestService service = ITestService.Stub.asInterface(b);
//创建TestServiceManager,第二个参数为BpBpTestService
return new TestServiceManager(ctx.getOuterContext(), service);
}});
registerService的第二个参数是一个ServiceFetcher对象,这里直接在调用时,新建了一个ServiceFetcher类,重写了createService方法。
ContextImpl.java中的registerService()方法,其核心就是把servicename和ServiceFetcher对象放到一个Hash的键值对中。
private static void registerService(String serviceName, ServiceFetcher fetcher) {
if (!(fetcher instanceof StaticServiceFetcher)) {
fetcher.mContextCacheIndex = sNextPerContextServiceCacheIndex++;
}
SYSTEM_SERVICE_MAP.put(serviceName, fetcher);
}
⑦ app如何使用service
那么app是如何调用的呢?
import android.app.TestServiceManager;
import android.content.Context;
TestServiceManager mTestServiceManager;
mTestServiceManager=(TestServiceManager)context.getSystemService(Context.TEST_SERVICE);
然后直接调用TestServiceManager中的方法即可,其中的奥秘需要分析下getSystemService函数。
ContextImpl.java中,
@Override
public Object getSystemService(String name) {
ServiceFetcher fetcher = SYSTEM_SERVICE_MAP.get(name);
//从ServiceFetcher 中获取service
return fetcher == null ? null : fetcher.getService(this);
}
getService()函数的核心就是上面重写的createService()函数,返回的就是TestServiceManager对象,所以通过context.getSystemService返回的是Manager对象。
public Object getService(ContextImpl ctx) {
ArrayListObject cache = ctx.mServiceCache;
Object service;
synchronized (cache) {
if (cache.size() == 0) {
// Initialize the cache vector on first access.
// At this point sNextPerContextServiceCacheIndex
// is the number of potential services that are
// cached per-Context.
for (int i = 0; i sNextPerContextServiceCacheIndex; i++) {
cache.add(null);
}
} else {
service = cache.get(mContextCacheIndex);
if (service != null) {
return service;
}
}
//调用重载的createService函数,返回的就是TestServiceManager对象
service = createService(ctx);
cache.set(mContextCacheIndex, service);
return service;
}
}
这几天突然要发一个中国台湾版本,做法比较硬:复制一个工程,改包名,改图标,改api接口。语言全部都是繁体就行:
Android studio添加新语言资源文件(res/values/....)如下:
然后回车即可:
把对应的字符串翻译成繁体就行。至于翻译,有一些工具可以借鉴。同时网上也有很多多语言切换的方式,就是一个工程,一个app进行内部切换多语言支持的方式(像微信就是。不过微信繁体有些不一定都支持了...)。具体看情况啦。。。
因为我们是整个app就是中国台湾台北版本,所以就都是繁体,不管系统是简体还是繁体还是别的,就是繁体!!!
简单记录下。好多东西没怎么关注或者使用,至于是否要深入,可能要看情况....
参考o: android--实现多语言支持 - snow_flower - 博客园
如您需要在Android系统手机上添加联系人请进入“联系人”——“MENU”——“导入联人”——“MENU——“全部导入”——Device 就把所有SIM上联系人导入到设备上了。(上述内容仅适用于广东联通用户)