Android的服务执行否认 [英] Android service execution denied
问题描述
我有一个 WakefulIntentService 实现的服务。它由开始它开始每一个适当的意图是颁发给在广播接收器
负责任时间。该服务开始于两种情况:在设备开机并在服务的运行实例即将完成,并通过询问Android的常规任务调度计划新的执行过程中, AlarmManager
,在未来时间发出起动意图
现在的问题是,我have被告知不要使用的android:出口=真正的
在出于安全原因,清单文件中声明的服务。然而,省略它会导致服务执行在测试手机之一被拒绝(三星S3运行的是Android 4.1.2):
十一月6日至13日:34:34.181:W / ActivityManager(2270):权限被拒绝:checkComponentPermission()owningUid = 10155
十一月6日至13日:34:34.181:W / ActivityManager(2270):拒绝权限:访问服务ComponentInfo {com.mypackage.myapp / com.mypackage.myapp.MyService}从PID = 10320,UID = 2000不是从出口UID 10155
添加的android:出口=真正的
解决问题。是否有避免拒绝执行不影响应用程序的安全性的方法吗?
该清单xml文件:
<?XML版本=1.0编码=UTF-8&GT?;
<清单的xmlns:机器人=http://schemas.android.com/apk/res/android
包=com.mypackage.myapp
安卓版code =3
机器人:=的versionName1.0> <用途-SDK
安卓的minSdkVersion =8
机器人:targetSdkVersion =17/> <使用许可权的android:NAME =android.permission.ACCESS_FINE_LOCATION/>
<使用许可权的android:NAME =android.permission.INTERNET对/>
<使用许可权的android:NAME =android.permission.READ_PHONE_STATE/>
<使用许可权的android:NAME =android.permission.RECEIVE_BOOT_COMPLETED/>
<使用许可权的android:NAME =android.permission.WAKE_LOCK/> <应用
机器人:allowBackup =真
机器人:图标=@绘制/ IC
机器人:标签=@字符串/ APP_NAME
机器人:主题=@风格/ AppTheme> <接收机器人:MyBroadcastReceiverNAME =>
&所述;意图滤光器>
<作用机器人:名字=android.intent.action.BOOT_COMPLETED/>
<类机器人:名字=android.intent.category.DEFAULT/>
&所述; /意图滤光器>
&所述;意图滤光器>
<作用机器人:名字=com.mypackage.myapp/>
&所述; /意图滤光器>
< /接收器> <服务
机器人:名字=com.mypackage.myapp.MyService
机器人:出口=真正的>
< /服务> < /用途>< /清单>
的广播接收器
:
包com.mypackage.myapp;进口android.content.BroadcastReceiver;
进口android.content.Context;
进口android.content.Intent;进口com.commonsware.cwac.wakeful.WakefulIntentService;公共类MyBroadcastReceiver扩展广播接收器{ @覆盖
公共无效的onReceive(上下文的背景下,意图意图){
WakefulIntentService.sendWakefulWork(背景下,MyService.class);
}
}
包含起动意图调度code在的onDestroy()服务
:
公共类的MyService扩展WakefulIntentService {(......) @覆盖
公共无效doWakefulWork(意向意图){
(......)
} @覆盖
公共无效的onDestroy(){ 的PendingIntent圆周率= PendingIntent.getBroadcast(在此,0,新意图(com.mypackage.myapp),0); AlarmManager点=(AlarmManager)(this.getSystemService(Context.ALARM_SERVICE)); am.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,ONE_MINUTE,PI); super.onDestroy();
}
}
其实它不会从开机出现,但是当我尝试手动启动它在亚行的shell:我startservice com.mypackage.myapp / .MyService
块引用>那就不要做。您的用户不会这么做。导出服务,只是让你可以运行
亚行外壳
命令,还不是一个特别明智的举动。此外,你可以测试从亚行外壳
发送启动时间播出,达到同样的目的,而不必导出服务。
我一直无法开机时,使服务开始我的新意图删除操作字符串后()
块引用>对不起,我的意思是你的第二个操作字符串。你的
<接收>
应该是这样的:<接收机器人:MyBroadcastReceiverNAME =>
&所述;意图滤光器>
<作用机器人:名字=android.intent.action.BOOT_COMPLETED/>
<类机器人:名字=android.intent.category.DEFAULT/>
&所述; /意图滤光器>
< /接收器>和相应的
的PendingIntent
是:的PendingIntent PI = PendingIntent.getBroadcast(这一点,0,新的意图(这一点,MyBroadcastReceiver.class),0);
I have a service implemented as a WakefulIntentService. It is started every time a proper intent is issued to the
BroadcastReceiver
responsible by starting it. The service starts in two situations: upon device boot and when a running instance of the service is about to finish and schedules a new execution by asking Android's conventional task scheduler, theAlarmManager
, to issue a starter intent at a future time.The question is, I have been advised not to use
android:exported="true"
in the service declared in the Manifest file for security reasons. However, omitting it causes the service execution to be denied in one of the test phones (a Samsung S3 running Android 4.1.2):06-13 11:34:34.181: W/ActivityManager(2270): Permission denied: checkComponentPermission() owningUid=10155 06-13 11:34:34.181: W/ActivityManager(2270): Permission Denial: Accessing service ComponentInfo{com.mypackage.myapp/com.mypackage.myapp.MyService} from pid=10320, uid=2000 that is not exported from uid 10155
Adding
android:exported="true"
fixes the problem. Is there an alternative to avoid the execution denial without compromising the app's security?The Manifest xml file:
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.mypackage.myapp" android:versionCode="3" android:versionName="1.0"> <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="17" /> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.READ_PHONE_STATE" /> <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" /> <uses-permission android:name="android.permission.WAKE_LOCK" /> <application android:allowBackup="true" android:icon="@drawable/ic" android:label="@string/app_name" android:theme="@style/AppTheme" > <receiver android:name=".MyBroadcastReceiver" > <intent-filter> <action android:name="android.intent.action.BOOT_COMPLETED" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter> <intent-filter> <action android:name="com.mypackage.myapp" /> </intent-filter> </receiver> <service android:name="com.mypackage.myapp.MyService" android:exported="true"> </service> </application> </manifest>
The
BroadcastReceiver
:package com.mypackage.myapp; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import com.commonsware.cwac.wakeful.WakefulIntentService; public class MyBroadcastReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { WakefulIntentService.sendWakefulWork(context, MyService.class); } }
The service containing the starter intent scheduling code in
onDestroy()
:public class MyService extends WakefulIntentService { (...) @Override public void doWakefulWork(Intent intent) { (...) } @Override public void onDestroy() { PendingIntent pi = PendingIntent.getBroadcast(this, 0, new Intent("com.mypackage.myapp"), 0); AlarmManager am = (AlarmManager)(this.getSystemService(Context.ALARM_SERVICE)); am.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, ONE_MINUTE, pi); super.onDestroy(); } }
解决方案Actually it doesn't occur from boot but when I attempt to start it manually on adb shell: am startservice com.mypackage.myapp/.MyService.
Then don't do that. Your users won't be doing that. Exporting a service, just so you can run an
adb shell
command, is not an especially wise move. Moreover, you can test sending the boot-time broadcast fromadb shell
, achieve the same end, and not have to export the service.I haven't been able to make the service start upon boot after removing the action string in my new Intent()
Sorry, I meant your second action string. Your
<receiver>
should look like:<receiver android:name=".MyBroadcastReceiver" > <intent-filter> <action android:name="android.intent.action.BOOT_COMPLETED" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter> </receiver>
And the corresponding
PendingIntent
would be:PendingIntent pi = PendingIntent.getBroadcast(this, 0, new Intent(this, MyBroadcastReceiver.class), 0);
这篇关于Android的服务执行否认的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!