android:enabled="true" service,Manifest中<android:enabled>和<android:exported>标签

晚上敲代码的时候,在一个Activity中给按钮添加点击事件,希望实现开启/关闭服务的功能。但是服务死活开启不了。反反复复检查了很多遍,Activity中的代码肯定是没有问题的。

settingBtn.setOnClickListener(new View.OnClickListener() {

@Override

public void onClick(View v) {

Intent intent = new Intent(getApplicationContext(), AntiService.class);

if (ServiceTool.getServiceState(getApplicationContext(), "com.example.dio.service.AntiService")) {//如果已经打开了,就将按钮关闭,并且关闭服务

stopService(intent);

settingBtn.setSelected(false);

} else {//如果没有打开,将按钮打开,并且开启服务

startService(intent);

settingBtn.setSelected(true);

}

}

});

最后才发现原来是在Manifest.xml文件中给Service下的enable和exported两个标签的设置问题。

下面是官方文档对这两个标签的解释:

android:enabled Whether or not the broadcast receiver can be instantiated by the system — "true" if it can be, and "false" if not. The default value is "true".

The element has its own enabled attribute that applies to all application components, including broadcast receivers. The and attributes must both be "true" for the broadcast receiver to be enabled. If either is "false", it is disabled; it cannot be instantiated.

android:exported Whether or not components of other applications can invoke the service or interact with it — "true" if they can, and "false" if not. When the value is "false", only components of the same application or applications with the same user ID can start the service or bind to it.

The default value depends on whether the service contains intent filters. The absence of any filters means that it can be invoked only by specifying its exact class name. This implies that the service is intended only for application-internal use (since others would not know the class name). So in this case, the default value is "false". On the other hand, the presence of at least one filter implies that the service is intended for external use, so the default value is "true".

This attribute is not the only way to limit the exposure of a service to other applications. You can also use a permission to limit the external entities that can interact with the service (see the permission attribute).

简单翻译一下

android:enabled 定义服务能否被系统实例化的标签,true表示可以实例化,false不能实例化,默认为true。

标签也有enabled标签,这个标签适用于application下所有组件。只有当和下enabled标签的属性都为true的时候,才可以将广播接受者启动(enabled),否则广播接受者不能开启(disabled),不能被实例化。

android:exported 定义服务能否被外部应用的组件调用或者交互,true表示可以,false表示不能。如果设置为false,服务只能接收本应用的组件或者是具有相同用户ID的应用所发出的所开启或绑定。

exported标签的默认属性根据该广播接受者是否有intent filter决定。如果没有定义任何intent filter,那么该服务只能由指定准确的类名(完整类名)的intent对象所调用,这就意味着服务只能在应用内部使用(因为其他应用通常不能获取到完整类名)。这种情况下,默认值就是false。而当服务中存在至少一个intent filter时,就意味着其可以在外部被调用,所以默认值就是true。

这个标签的属性并不是限制服务对外暴露的唯一方式,通过权限(permission)也可以实现。

除了service,receiver也有这两个标签,分别对应的是能否被实例化和能否接受外部消息。

因为之前一开始用eclipse的时候,添加服务并不会提示这两个标签,应该都是默认的。后来用Android Studio,当在应用中创建BroadReceiver的时候,会默认的在Manifest.xml中注册并且添加这两个标签。之前因为没有关注过着两个标签,所以一直默认的。这次不知道什么时候都设置成了false,所以才会无法创建这个服务。

还是平时文档看的不够仔细,学习Android还有很长的路要走。

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
activity_main.xml <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@drawable/bg"> <Button android:id="@+id/btn_start" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginBottom="90dp" android:text="开启服务" android:layout_above="@+id/btn_stop" android:layout_centerHorizontal="true" android:background="#B0E0E6" android:textSize="18sp" android:onClick="start"/> <Button android:id="@+id/btn_stop" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="关闭服务" android:layout_alignParentBottom="true" android:layout_alignLeft="@+id/btn_start" android:layout_alignStart="@+id/btn_start" android:layout_marginBottom="20dp" android:background="#F08080" android:textColor="#6C6C6C" android:textSize="18sp" android:onClick="stop"/> </RelativeLayout> MainActivity package com.example.startservice; import android.content.Intent; import android.os.Bundle; import android.view.View; import androidx.appcompat.app.AppCompatActivity; public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } // 开启服务 public void start(View view){ Intent intent = new Intent(this,MyService.class); startService(intent); } // 关闭服务 public void stop(View view){ Intent intent = new Intent(this,MyService.class); stopService(intent); } } MyService package com.example.startservice; import android.app.Service; import android.content.Intent; import android.os.IBinder; import android.util.Log; public class MyService extends Service { public MyService() { } @Override public IBinder onBind(Intent intent) { throw new UnsupportedOperationException("Not yet implemented"); } @Override public void onCreate() { super.onCreate(); Log.i("StartService","onCreate()"); } @Override public int onStartCommand(Intent intent,int flags, int startId) { Log.i("StartService","onStartCommand()"); return super.onStartCommand(intent, flags, startId); } @Override public void onDestroy() { super.onDestroy(); Log.i("StartService","onDestroy()"); } } AndroidManifest.xml <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.startservice"> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/AppTheme"> <activity android:name=".MainActivity"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <service android:name=".MyService" android:enabled="true" android:exported="true"></service> </application> </manifest>实验步骤
06-03

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值