Android的服务执行否认 [英] Android service execution denied

查看:271
本文介绍了Android的服务执行否认的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个 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:机器人=htt​​p://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, the AlarmManager, 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 from adb 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆