web-dev-qa-db-ja.com

Androidでカスタム権限を使用する方法は?

2つのアプリケーションがあります。

1つは、許可を宣言し、単一のActivityを持つことです。

AndroidManifest.xmlの一部

<application
    Android:icon="@drawable/ic_launcher"
    Android:label="@string/app_name"
    Android:permission="your.namespace.permission.TEST" >
    <activity
        Android:name=".DeclaringPermissionActivity"
        Android:label="@string/app_name" >

        <intent-filter>
            <action Android:name="Android.intent.action.MAIN" />

            <category Android:name="Android.intent.category.LAUNCHER" />
        </intent-filter>

        <intent-filter> 
         <action Android:name="Android.intent.action.VIEW" /> 
         <category Android:name="Android.intent.category.DEFAULT" /> 
         <category Android:name="Android.intent.category.BROWSABLE" /> 
         <data Android:scheme="myapp"
             Android:Host="myapp.mycompany.com" /> 
        </intent-filter> 
    </activity>
</application>

2番目は、許可を使用することを宣言します

AndroidManifest.xmlの一部

<uses-sdk Android:minSdkVersion="10" />
<uses-permission Android:name="your.namespace.permission.TEST" />

<application

Activityの一部:

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("myapp://myapp.mycompany.com/index")));
}

許可を宣言するアプリケーションをインストールしてから、2番目のアプリケーションを実行します。

その結果、セキュリティ例外が発生します。

 01-11 09:46:55.249: E/AndroidRuntime(347): Java.lang.RuntimeException: Unable to start activity ComponentInfo{your.namespace2/your.namespace2.UsingPErmissionActivity}: Java.lang.SecurityException: Permission Denial: starting Intent { act=Android.intent.action.VIEW dat=myapp://myapp.mycompany.com/index cmp=your.namespace/.DeclaringPermissionActivity } from ProcessRecord{407842c0 347:your.namespace2/10082} (pid=347, uid=10082) requires your.namespace.permission.TEST
56
pixel

テストコードを作成し、それを使用してアクセス許可をテストできます。許可を宣言し、この許可でそのアクティビティを保護する2つのアプリケーションPermissionTestClientがあります。マニフェストファイルは次のとおりです。

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:Android="http://schemas.Android.com/apk/res/Android"
    package="com.testpackage.permissiontestclient"
    Android:versionCode="1"
    Android:versionName="1.0" >

    <uses-sdk Android:minSdkVersion="10" />
    <permission Android:name="com.testpackage.mypermission" Android:label="my_permission" Android:protectionLevel="dangerous"></permission>

    <application
        Android:icon="@drawable/ic_launcher"
        Android:label="@string/app_name" >
        <activity
            Android:permission="com.testpackage.mypermission"
            Android:name=".PermissionTestClientActivity"
            Android:label="@string/app_name" >
            <intent-filter>
                <action Android:name="Android.intent.action.MAIN" />

                <category Android:name="Android.intent.category.LAUNCHER" />
            </intent-filter>

            <intent-filter >
                <action Android:name="com.testpackage.permissiontestclient.MyAction" />
                <category Android:name="Android.intent.category.DEFAULT" />                
            </intent-filter>
        </activity>
    </application>

</manifest>

アクティビティファイルには特別なものはないため、ここでは表示しません。

PermissionTestServerアプリケーションは、PermissionTestClientからアクティビティを呼び出します。マニフェストファイルは次のとおりです。

<?xml version="1.0" encoding="utf-8"?>
<uses-sdk Android:minSdkVersion="10" />
<uses-permission Android:name="com.testpackage.mypermission"/>

<application
    Android:icon="@drawable/ic_launcher"
    Android:label="@string/app_name" >
    <activity
        Android:name=".PermissionTestServerActivity"
        Android:label="@string/app_name" >
        <intent-filter>
            <action Android:name="Android.intent.action.MAIN" />

            <category Android:name="Android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
</application>

</manifest>

そしてアクティビティ:

package com.testpackage.permissiontestserver;

import Android.app.Activity;
import Android.content.Intent;
import Android.os.Bundle;
import Android.util.Log;
import Android.view.View;
import Android.view.View.OnClickListener;
import Android.widget.Button;

public class PermissionTestServerActivity extends Activity {
    private static final String TAG = "PermissionTestServerActivity";

    /** Called when the activity is first created. */
    Button btnTest;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        btnTest = (Button) findViewById(R.id.btnTest);
        btnTest.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                Log.d(TAG, "Button pressed!");
                Intent in = new Intent();
                in.setAction("com.testpackage.permissiontestclient.MyAction");
                in.addCategory("Android.intent.category.DEFAULT");
                startActivity(in);
            }
        });
    }
}

テストするには、サーバーアプリケーションからuses-permissionを削除するだけです。セキュリティ違反エラーが表示されます。

102
Yury

ベースアプリのマニフェストに排他的に宣言することにより、許可を作成する必要があります。例えば:

<permission Android:name="your.namespace.permission.TEST"
    Android:protectionLevel="normal" Android:label="This is my custom  permission" />

その後、目的のアプリで次のように使用します。

<uses-permission Android:name="your.namespace.permission.TEST" />

注:カスタムパーミッションでアプリケーションをインストールする順序を維持することが重要です。つまり、そのアプリをインストールする必要がありますfirst許可を宣言し、後でそれを使用するものをインストールします。この順序で混乱が生じると、custom。権限の使用が中断される場合があります。

32
waqaslam

回答で述べたように、アプリをインストールする順序も考慮する必要があります。

これは重要です:

許可を要求するアプリ(App B)が許可を定義するアプリ(App A)の前にインストールされている場合、特定のデバイスにはそのような定義された許可がないため、OSは許可をまったく要求しません。

後で、アプリAをインストールしてアプリBを実行しようとすると、アプリBがセキュアコンポーネントにアクセスできなくなります。

回避策の1つは、アプリAとBの両方で同じカスタム権限を定義して、最初にインストールするアプリに関係なくデバイスに権限が存在することを確認することです。したがって、アプリAをインストールすると、権限は既にApp Bに付与されます。

ただし、その場合、両方の宣言で保護レベルが同じであることを確認する必要があります。これはセキュリティリスクにつながる可能性があるためです。

(ここで、from Android 5.0以降では、同じ署名キーで署名されたアプリを除き、複数のアプリで同じ権限を定義できないことに注意してください)。

3
Adam

カスタム許可の定義は、<Permission>タグを使用して行われます。アプリケーションでユーザー定義の許可を使用するには、以下のリンクに従ってください。

権限の宣言と適用

1
Lavakush