ContentProvier使用时:java.lang.SecurityException: Permission Denial:XXX解决办法

本文介绍了一个关于Android中ContentProvider权限拒绝的问题及其解决方案。问题出现在尝试从不同进程访问未导出的ContentProvider时,通过在AndroidManifest.xml中设置provider的exported属性为true解决了跨进程访问的问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

提示错误

Permission Denial:opening provider com.example.db.PersonProvider from ProcessRecord{2c6e34f0 24384:com.dzr.other2/u0a10051} (pid=24384, uid=10051) that is not exported from uid 10050
at android.os.Parcel.readException(Parcel.java:1425)
at android.os.Parcel.readException(Parcel.java:1379)
at android.app.ActivityManagerProxy.getContentProvider(ActivityManagerNative.java:2530)
at android.app.ActivityThread.acquireProvider(ActivityThread.java:4460)
at android.app.ContextImpl$ApplicationContentResolver.acquireProvider(ContextImpl.java:1987)
at android.content.ContentResolver.acquireProvider(ContentResolver.java:1054)
at android.content.ContentResolver.insert(ContentResolver.java:860)
at com.dzr.test.AccessContentProvierTest.testInsert(AccessContentProvierTest.java:21)
at java.lang.reflect.Method.invokeNative(Native Method)
at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:190)
at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:175)
at android.test.InstrumentationTestRunner.onStart(InstrumentationTestRunner.java:555)
at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1661)</span>


 
测试代码
</pre><pre code_snippet_id="468846" snippet_file_name="blog_20140915_5_275383" name="code" class="java">
package com.dzr.test;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.net.Uri;
import android.test.AndroidTestCase;

public class AccessContentProvierTest extends AndroidTestCase
{

	public void testInsert()throws Exception
	{
		Uri uri = Uri.parse("content://cn.dzr.personprovider/person");
		ContentResolver resolver = this.getContext().getContentResolver();
		ContentValues values = new ContentValues();
		
		values.put("name", "laoli");
		values.put("phone", "13786788939");
		values.put("amount", 12212121);
		
		resolver.insert(uri, values);
	}
}

程序代码

package com.example.db;

import com.example.service.DbOpenHelper;

import android.content.ContentProvider;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.net.Uri;

public class PersonProvider extends ContentProvider
{

	private DbOpenHelper dbOpenHelper;
	private static final UriMatcher MATCHER = new UriMatcher(UriMatcher.NO_MATCH);
	private static final int PERSONS = 1;
	static{
		MATCHER.addURI("cn.dzr.personprovider", "person", PERSONS);
	}
	public boolean onCreate()
	{
		dbOpenHelper = new DbOpenHelper(this.getContext());
		return true;
	}
	@Override
	public int delete(Uri arg0, String arg1, String[] arg2)
	{
		// TODO Auto-generated method stub
		return 0;
	}

	@Override
	public String getType(Uri uri)
	{
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public Uri insert(Uri uri, ContentValues values)
	{
		SQLiteDatabase db = this.dbOpenHelper.getWritableDatabase();
		
		switch(MATCHER.match(uri))
		{
		case 1:
			long rowid = db.insert("person", null, values);
		
		//	Uri insertUri = Uri.parse("content://cn.dzr.personprovider/person" + rowid);
			Uri insertUri = ContentUris.withAppendedId(uri, rowid);
			return insertUri;
			
		default:
			throw new IllegalArgumentException("this is an unknow Uri:" + uri);
			
			  
		}		
	}

	

	@Override
	public Cursor query(Uri uri, String[] projection, String selection,
			String[] selectionArgs, String sortOrder)
	{
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public int update(Uri uri, ContentValues values, String selection,
			String[] selectionArgs)
	{
		// TODO Auto-generated method stub
		return 0;
	}

}
解决办法

AndroidManifest.xml里加入

 <provider   android:exported = "true" />

### Java HTTP 请求中的权限拒绝解决方案 当执行 HTTP 请求遇到 `SecurityException` 权限被拒的情况,通常是因为应用程序缺少必要的网络访问权限。对于 Android 应用程序而言,在发起任何类型的网络连接之前,必须声明并获取相应的权限。 #### 声明网络权限 为了使应用能够正常发送 HTTP 请求,需在项目的 `AndroidManifest.xml` 文件中添加如下权限声明[^2]: ```xml <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/> <uses-permission android:name="android.permission.INTERNET"/> ``` 上述配置允许应用查询设备当前的网络状态以及通过互联网传输数据的能力。 #### 动态权限处理 自 Android 6.0 (API level 23) 起,部分敏感权限需要运行动态申请。针对此情况下的 HTTP 请求操作,建议实现类似以下逻辑来验证特定用户 ID 是否已授予所需权限: ```java public class PermissionUtil { private final Context context; public PermissionUtil(Context context){ this.context = context; } /** * 检查给定名称的权限是否已被授权. */ public boolean checkSelfPermission(String permissionName, int userId){ PackageManager packageManager = context.getPackageManager(); return packageManager.hasSystemFeature(permissionName, userId); } } ``` 注意这里的 `hasSystemFeature()` 方法用于模拟原生框架内的权限检查机制[^1];实际开发环境中应使用 `ContextCompat.checkSelfPermission()` 或者其他官方推荐的方式来进行权限检测。 如果发现权限未授,则可以通过调用 `ActivityCompat.requestPermissions()` 向用户请求相应权限。 #### SELinux 配置影响 另外值得注意的是,SELinux 的强制模式也可能阻止某些进程间的通信行为。虽然默认情况下该函数返回值设置为 `false` 表示采用宽容策略[^3],但在生产环境部署前仍需确认目标系统的安全增强 Linux 设置不会干扰到正常的业务流程。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值