GVKun编程网logo

android – E / ActivityThread:无法找到com.example.YPLContentProvider的提供者信息

15

本文将介绍android–E/ActivityThread:无法找到com.example.YPLContentProvider的提供者信息的详细情况,。我们将通过案例分析、数据研究等多种方式,帮助您

本文将介绍android – E / ActivityThread:无法找到com.example.YPLContentProvider的提供者信息的详细情况,。我们将通过案例分析、数据研究等多种方式,帮助您更全面地了解这个主题,同时也将涉及一些关于@AndroidEntryPoint 基类必须扩展 ComponentActivity、(支持)Fragment、View、Service 或 BroadcastReceiver、Android AppCompatActivity的ActionBar之SearchView、ShareActionProvider以及menu、Android Contacts (android通讯录读取)-content provider、Android Content Provider (内容提供者)的知识。

本文目录一览:

android – E / ActivityThread:无法找到com.example.YPLContentProvider的提供者信息

android – E / ActivityThread:无法找到com.example.YPLContentProvider的提供者信息

我在 Android应用程序的日志中收到这样的消息.

E/ActivityThread﹕ Failed to find provider info for
com.example.myapp.YPLContentProvider

我搜索过,但没有找到YPLContentProvider的任何参考.我没有在我的代码中使用或实现这样的类.

还有

E/ActivityThread﹕ Failed to find provider info for
com.example.myapp.MetrikaContentProvider

这是什么?

解决方法

它不是来自您的应用程序的日志.
您的设备上似乎安装了一些Yandex安卓应用程序(如Yandex.Maps),它们为您设备中的每个应用程序寻找指标提供程序(不需要的行为,但它可以正常运行),包括您开发的应用程序.

01-25 15:23:15.745 22000-22044/ru.yandex.yandexmaps E/ActivityThread﹕ Failed to find provider info for com.vhqlabs.TextPoll.YPLContentProvider

@AndroidEntryPoint 基类必须扩展 ComponentActivity、(支持)Fragment、View、Service 或 BroadcastReceiver

@AndroidEntryPoint 基类必须扩展 ComponentActivity、(支持)Fragment、View、Service 或 BroadcastReceiver

如何解决@AndroidEntryPoint 基类必须扩展 ComponentActivity、(支持)Fragment、View、Service 或 BroadcastReceiver?

我正在尝试使用 viewmodel 并观察我的 DialogFragment 中的数据,我也在注入 viewmodel,同时实现代码时出错。 PFB 我的代码片段。并帮助我找到合适的解决方案。

  1. 当前对话框片段

@AndroidEntryPoint 公共类 MyFragmentFragment 扩展了 DialogFragment 实现了 View.OnClickListener {

public View onCreateView(@NonNull LayoutInflater inflater,ViewGroup container,Bundle savedInstanceState) {
        mBinding = DataBindingUtil.inflate(inflater,R.layout.fragment_buycourse,container,false);
        myviewmodel = new viewmodelProvider(this).get(Myviewmodel.class);

        view = mBinding.getRoot();

        initViews();

        return view;
    }
        public static MyFragmentFragment newInstance(){
            return new MyFragmentFragment ();
        }
    }
    
  1. 代码中的父片段

@AndroidEntryPoint 公共类 HomeFragment 扩展 Fragment {

public View onCreateView(@NonNull LayoutInflater inflater,ViewGroup 容器,Bundle savedInstanceState) {

    mBinding.startBtn.setonClickListener(v -> {
                DialogFragment dialog = new MyFragmentFragment ();
                dialog.setStyle(DialogFragment.STYLE_NO_TITLE,R.style.Theme_Learn365_NoActionBar);
                dialog.show(requireActivity().getFragmentManager(),"MyFragment");
    }
    }
    }
    
    

当我运行它时,我得到“@AndroidEntryPoint 基类必须扩展 ComponentActivity、(支持)Fragment、View、Service 或 broadcastReceiver。”而且我无法在 DialogFragment 中注入 viewmodel。

解决方法

我通过替换 DialogFragment 导入 解决了这个问题,并且它的工作正常;

旧进口: 导入 android.app.DialogFragment;

新导入: import androidx.fragment.app.DialogFragment;

Android AppCompatActivity的ActionBar之SearchView、ShareActionProvider以及menu

Android AppCompatActivity的ActionBar之SearchView、ShareActionProvider以及menu



Android AppCompatActivity的ActionBar之SearchView、ShareActionProvider以及menu

Android早期推出的ActionBarActivity被Android谷歌官方废弃,推荐使用AppCompatActivity替代ActionBarActivity。在实际的开发中现在也基本上不再怎么使用ActionBar,而是使用最新的Toolbar替代ActionBar了,但是ActionBar也有其自身比较有特点的地方,比如ActionBar自身对SearchView,ShareActionProvider的良好支持,使得ActionBar在某些应用开发场景中依然有其用武之地。
现在给出一个例子说明如何在一个ActionBar中实现SearchView和ShareActionProvider。
先把完整的代码实现给出,然后结合代码加以说明。
测试用的主Activity,MainActivity.java:

package zhangphil.toolbar;

import android.content.Intent;
import android.os.Bundle;
import android.support.v4.view.MenuItemCompat;
import android.support.v4.view.MenuItemCompat.OnActionExpandListener;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.SearchView;
import android.support.v7.widget.SearchView.OnQueryTextListener;
import android.support.v7.widget.ShareActionProvider;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		ActionBar ab = this.getSupportActionBar();
		ab.setDisplayHomeAsUpEnabled(true);
	}

	private Intent getMyIntent() {
		Intent intent = new Intent(Intent.ACTION_SEND);
		intent.setType("text/plain");
		intent.putExtra(Intent.EXTRA_SUBJECT, "主题");
		intent.putExtra(Intent.EXTRA_TEXT, "我的文字内容,zhangphil text");
		return intent;
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		getMenuInflater().inflate(R.menu.main, menu);

		MenuItem searchItem = menu.findItem(R.id.search);
		SearchView searchView = (SearchView) MenuItemCompat.getActionView(searchItem);
		searchView.setOnQueryTextListener(new OnQueryTextListener() {
			@Override
			public boolean onQueryTextChange(String queryText) {
				Toast.makeText(getApplicationContext(), "onQueryTextChange:" + queryText, Toast.LENGTH_SHORT).show();
				return true;
			}

			@Override
			public boolean onQueryTextSubmit(String queryText) {
				Toast.makeText(getApplicationContext(), "onQueryTextSubmit:" + queryText, Toast.LENGTH_SHORT).show();
				return true;
			}
		});

		OnActionExpandListener expandListener = new OnActionExpandListener() {
			@Override
			public boolean onMenuItemActionCollapse(MenuItem item) {
				Toast.makeText(getApplicationContext(), "onMenuItemActionCollapse", Toast.LENGTH_SHORT).show();
				return true;
			}

			@Override
			public boolean onMenuItemActionExpand(MenuItem item) {
				Toast.makeText(getApplicationContext(), "onMenuItemActionExpand", Toast.LENGTH_SHORT).show();
				return true;
			}
		};

		MenuItemCompat.setOnActionExpandListener(searchItem, expandListener);

		MenuItem shareItem = menu.findItem(R.id.share);
		ShareActionProvider shareActionProvider = (ShareActionProvider) MenuItemCompat.getActionProvider(shareItem);
		shareActionProvider.setShareIntent(getMyIntent());

		return super.onCreateOptionsMenu(menu);
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		switch (item.getItemId()) {

		case R.id.share:
			Toast.makeText(getApplicationContext(), "分享", Toast.LENGTH_SHORT).show();
			return true;

		case R.id.setting:
			Toast.makeText(getApplicationContext(), "设置", Toast.LENGTH_SHORT).show();
			return true;

		case R.id.about:
			Toast.makeText(getApplicationContext(), "关于", Toast.LENGTH_SHORT).show();
			return true;

		default:
			return super.onOptionsItemSelected(item);
		}
	}
}


在本例中,MainActivity.java不依赖任何布局文件,只是需要加载menu菜单,所以需要在res/menu/目录下写一个menu菜单的XML文件,定义menu的item,此代码文件在本例中称之为main.xml:

<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools" >

    <item
        android:id="@+id/search"
        android:title="搜索"
        app:actionViewapp:showAsAction="ifRoom|collapseActionView"/>
    <item
        android:id="@+id/share"
        android:title="分享"
        app:actionProviderapp:showAsAction="ifRoom|withText"/>
    <item
        android:id="@+id/setting"
        android:title="设置"
        app:showAsAction="never"/>
    <item
        android:id="@+id/about"
        android:title="关于"
        app:showAsAction="ifRoom"/>

</menu>

在MainActivity.java中的一个方法体中,重写:
public boolean onCreateOptionsMenu(Menu menu);
方法将依据res/menu/main.xml文件创建菜单。在这个方法中,为id为search的menu item创建响应搜索事件。同时,附带的为搜索item绑定了展开和收缩事件:

OnActionExpandListener expandListener = new OnActionExpandListener() {
			@Override
			public boolean onMenuItemActionCollapse(MenuItem item) {
				Toast.makeText(getApplicationContext(), "onMenuItemActionCollapse", Toast.LENGTH_SHORT).show();
				return true;
			}

			@Override
			public boolean onMenuItemActionExpand(MenuItem item) {
				Toast.makeText(getApplicationContext(), "onMenuItemActionExpand", Toast.LENGTH_SHORT).show();
				return true;
			}
		};

		MenuItemCompat.setOnActionExpandListener(searchItem, expandListener);


对于菜单中分享菜单share item,则为其设置了ShareActionProvider,提供分享事件的数据和动作支持:

MenuItem shareItem = menu.findItem(R.id.share);
		ShareActionProvider shareActionProvider = (ShareActionProvider) MenuItemCompat.getActionProvider(shareItem);
		shareActionProvider.setShareIntent(getMyIntent());


其他次要普通的菜单选择事件则放在
public boolean onOptionsItemSelected(MenuItem item);
中完成。


图1是代码运行后,点击分享icon切换到微信的ActionBar状态:




图2则是点击了搜索item时候的ActionBar状态:


Android Contacts (android通讯录读取)-content provider

Android Contacts (android通讯录读取)-content provider

Android Contacts (android通讯录读取)-content provider

Content Provider

在数据处理中,Android通常使用Content Provider的方式。Content Provider使用Uri实例作为句柄的数据封装的,很方便地访问地进行数据的增、删、改、查的操作。Android并不提供所有应用共享的数据存储,采用content Provider,提供简单便捷的接口来保持和获取数据,也可以实现跨应用的数据访问。简单地说,Android通过content Provider从数据的封装中获取信息。

Content provider使用Uri的方式来定位信息。以“content://” 开头来表明这是一个content URI。例如“content://contstans/5”,其中“content://constans”称为base URI,相当于数据的namespace,它的结构可以更为复杂,可以有多层结构。例子中的“5”,则是具体实例的标识。

一般来讲,Android的数据存储有4种方式:

1、 Preferences,参见Preference的使用,通常都是键值对(name-value pair)。
2、文件:在手机设备或者外设上存储,缺省的只能由创建的应用访问。
3、数据库(RDBMS):SQLite方式,参见SQLite的使用,由创建的应用访问。
4、网络:Android提供API远程在服务器上存储数据。

如果我们需要在应用中共享,采用Content Provider。无论数据具体的存储方式,Content Provider提供了一个统一的接口。数据将采用类表格的方式提供,有行有列,列表示不同属性的数据,例如电话号码、电邮地址等。每个记录(每行)都有一个唯一的_ID字段来标识。在以后具体的代码中看更直观看出。

原生providers

Android提供一些原生的content provider,来往问系统中的视频、图像和联系人信息等等。例如联系人的URI为“content://com.android.contacts /contacts”,原生的providers一般都有定义,例如联系人为 ContactsContract.Contacts.CONTENT_URI。由于系统不同版本可能会存在差异,我们应尽可能使用系统的定义。

在android.provider的包中,可以查看原生的provider,例如有AlarmClock、Browser、CalendarContract、CallLog、 ContactsContract(包括有Contacts,Groups,PhoneLookup等)、MediaStore(Audio 『Albums、Artists、Genres、Playlists』、Files、Images、Video)和Setting。

通过Content Providers读取信息

我们利用原生provider联系人来看看如何来读取信息,联系人的数据结构比较复杂,后面会详细介绍,这里我们将尽可能简化,先对Content Provider有个直观的认识。核心是通过managedQuery( )来获取Cursor。Cursor实际返回是一个二维的表格,有行有列,行是具体的元素,列是该元素具体的属性。整个方式和SQLite非常相似。

//可以很方便将Cursor的内容映射到ListActivity上,具体参见Android学习笔记(四十二):SQLite,ListView,ContextMenu
public class Chapter26Test1 extendsListActivity {
    private String[] INFO = new String[]{
        ContactsContract.Contacts._ID, //对于Content Provider返回数据表格而言,注意唯一标识_ID通常是必须读取的,否则很容易报错
        ContactsContract.Contacts.DISPLAY_NAME,
        ContactsContract.Contacts.HAS_PHONE_NUMBER
    };
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
       
        Cursor contactCursor = managedQuery(ContactsContract.Contacts.CONTENT_URI,INFO, null,null,null);
                                                  ListAdapter adapter = new SimpleCursorAdapter(this,
                                                  R.layout.chapter_22_test1,contactCursor,
                                                  new String[]{ContactsContract.Contacts.DISPLAY_NAME,ContactsContract.Contacts.HAS_PHONE_NUMBER},
                                                  new int[]{R.id.c22_name,R.id.c22_gravity});
        setListAdapter(adapter); //偷偷懒,本例子直接利用了Android学习笔记(四十二)中SQLite例子中的xml
    }
}

说说Android联系人信息的组织结构及读取

这是Android给出的联系人组织结构图。分为三层。

第一层,Contact,即ContactContract.Contacts,是整合的联系人信息。

第二层,RawConact,即 ContactContract.RawContact,记录的是该联系人来自某信息源的信息,例如本地输入的,来自Google的,从微软 Exchange中导出的,或则来自某个社交网站的信息。每个RawContact记录的信息都来自同一信息源。

第三层,Data,即 ContactContract.Data,是具体的信息存储,例如记录联系人姓名,email信息,家庭电话,手机电话信息等等,每一个Data都存放一个具体的信息。在Data中的MIME TYPE说明存储信息的类型。具体在ContactContract.CommonDataKinds中定义。每个Data中有DATA1-DATA15 个字段来存储信息,各字段所代表的含义,也可以在CommonDataKinds中具体查到。

下面,我们一层一层地读取联系人信息,将更清晰地看到这个结构。要读取详细信息,对于Content Privider,关键是Uri逐层定位,才能获取信息。为了清晰表述,我们将整个路径写出来。

第一层信息,将返回联系人列表中的多个Contacts,Uri为ContactsContract.Contacts.CONTENT_URI

private String[] INFO_1= new String[]{
    ContactsContract.Contacts._ID,//这是每个row,也就是每个联系人的唯一的ID标识
    ContactsContract.Contacts.DISPLAY_NAME,
};
Cursor cursor = managedQuery(ContactsContract.Contacts.CONTENT_URI,INFO_1,null,null,null);

cursor是表格形式,每一个行表示一个联系人。要 读取哪些列,在第二个参数String[]中定义。可以选取那些列,在Android Reference中的ContactsContract.Contacts中的Column中可以查到。最关键的列信息为_ID,它是行,也就是每个联系人的唯一标识。除此之外,每个联系人的信息会根据旗下的RawContact进行整合,因此,我们可以查到联系的名字 ContactsContract.Contacts.DISPLAY_NAME等。

利用Contacts._ID,我们可以检索第二层的信息。

第二层信息,将返回某联系人的多个RawContacts

同样,返回表格中的列,可以查看 ContactsContract.RawContacts中查看。我们选取下面的信息,此外,如果要查看信息的来源,例如来自com.google,可通过RawContacts.ACCOUNT_TYPE和RawContacts.ACCOUNT_NAME两个列查看。

private String[ ] INFO_2 = {
    ContactsContract.RawContacts._ID, //这是RawContact的唯一标识
    ContactsContract.RawContacts.CONTACT_ID, //这是该RawContact关联的Contact._ID
};

通过查询全部的RawContacts,通过条件检索,要求联系人的ID为指定的某联系人。在下面的例子在managedQuery中给出了param3和param4的条件,注意参数3,如果我们有多个条件,可以用AND等逻辑符合进行表述。

Cursor cursor = managedQuery(ContactsContract.RawContacts.CONTENT_URI ,
                                                     INFO_2 ,
                                          RawContacts.CONTACT_ID + "=?" ,
                                          new String[]{String.valueOf(contactId)} ,
                                                    null);

通过RawContacts._ID,我们可以往下检索RawContacts下面各Data的信息内容。

第三层信息:将返回某RawContact的各Data的信息

可查询各列的信息见ContactsContract.Data的介绍。

private String INFO_3[] = {
    ContactsContract.Data._ID, //这是Data信息块的唯一标识
    ContactsContract.Data.CONTACT_ID, //关联第一层信息的CONTACT_ID
    ContactsContract.Data.RAW_CONTACT_ID, //关联第二层信息的RAW_IDCONTACT_ID
    ContactsContract.Data.MIMETYPE, //具体含义可查ContactsContract.CommonDataKinds
    ContactsContract.Data.DATA1, //通常读取DATA1就可以,在具体的ContactsContract.CommonDataKinds.Phone/Email等查到DATA1-DATA15的含义
    ContactsContract.Data.DATA2,
    … …
    ContactsContract.Data.DATA15,
};

读取的方式有两种。

方式一:指定定具体的Uri:

Uri rawContactUri = ContentUris.withAppendedId(ContactsContract.RawContacts.CONTENT_URI, rawId);
Uri dataUri =Uri.withAppendedPath(rawContactUri,ContactsContract.RawContacts.Data.CONTENT_DIRECTORY);
Cursor cursor = managedQuery( dataUri, INFO_3,null, null, null);

方式二:另一种是利用RawContacts_ID或者Contact_ID,通过Data.CONTENT_URI,具体方式类RawContacts的检索。

Cursor cursor = managedQuery(ContactsContract.Data.CONTENT_URI ,
                                                     INFO_3 ,
                                          ContactsContract.Data.RAW_CONTACT_ID + "=?" ,
                                          new String[]{String.valueOf(rawId)} ,
                                                    null);

总结一下架构图。实际上Android的联系人提供了多种URI的的查询方式,具体参加Android的reference。

posted @ 2015-06-11 15:14 laughingQing 阅读( ...) 评论( ...) 编辑 收藏

Android Content Provider (内容提供者)

Android Content Provider (内容提供者)

什么是 Content Provider

  • 应用程序间共享数据的一种方式
  • 为存储和获取数据提供了统一的接口
  • Android 为常见的一些数据提供了默认的 ContentProvider
  • Uri : 通用资源标识符

 创建和使用 Content Provider 的步骤:

图片从视频网上 copy 的

下面写一个利用 Content Provider 读取手机通讯录联系人姓名,并将名字显示在 TextView 中

xml 代码

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".Demo01">

    <TextView
        android:id="@+id/module_act_people_tv"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        />

</android.support.constraint.ConstraintLayout>

Java 代码,里面该有的都注释了

public class Demo01 extends AppCompatActivity {

    private TextView people_tv;

    //希望获得姓名(通讯录内的姓名)
    private String columns = ContactsContract.Contacts.DISPLAY_NAME;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_demo01);
        people_tv = findViewById(R.id.module_act_people_tv);
        //将联系人信息显示出来
        people_tv.setText(getQueryData());
        //添加访问系统通讯录权限
        //<uses-permission android:name="android.permission.READ_CONTACTS" />
    }
    private CharSequence getQueryData(){
        //用于保存获取的联系人
        StringBuilder stringBuilder = new StringBuilder();
        ContentResolver resolver = getContentResolver();
        //查询记录
        Cursor cursor = resolver.query(ContactsContract.Contacts.CONTENT_URI, null, null, null, null, null);
        //获取姓名记录的索引值
        int displayNameIndex = cursor.getColumnIndex(columns);
        //迭代获取索引
        for (cursor.moveToFirst();!cursor.isAfterLast();cursor.moveToNext()){
            String displayName = cursor.getString(displayNameIndex);
            stringBuilder.append(displayName+"\n");

        }
        //关闭cursor
        cursor.close();
        return  stringBuilder.toString();
    }

}

 

关于android – E / ActivityThread:无法找到com.example.YPLContentProvider的提供者信息的问题就给大家分享到这里,感谢你花时间阅读本站内容,更多关于@AndroidEntryPoint 基类必须扩展 ComponentActivity、(支持)Fragment、View、Service 或 BroadcastReceiver、Android AppCompatActivity的ActionBar之SearchView、ShareActionProvider以及menu、Android Contacts (android通讯录读取)-content provider、Android Content Provider (内容提供者)等相关知识的信息别忘了在本站进行查找喔。

本文标签: