使用 GMail app android 附加 apk 文件时权限被拒绝 [英] Permisssion denied while attaching apk file with GMail app android

查看:39
本文介绍了使用 GMail app android 附加 apk 文件时权限被拒绝的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个要求通过share Intent发送一个apk文件,我也没有任何麻烦地实现了.但问题仅在通过 GMail 发送 apk 时出现,我在尝试附加时收到 permission denied.我真的不知道 GMail 发生了什么.请通过您的答案和解决方案帮助我.任何小提示和技巧也对我有用.提前致谢

I have a requirement to send a apk file through share Intent and I have also implemented without any hassle. But the problem arises only while sending apk via GMail, I am getting permission denied while i try to attach. I really dont know what is happening with GMail. Kindly help me through your answers and solutions. Any Small hint and tips would also be useful for me. Thanks in advance

我正在使用以下代码通过共享意图发送 APK:

 public static void appSend(ArrayList<File> files,Context context){
        Intent shareIntent = new Intent(Intent.ACTION_SEND_MULTIPLE);
        shareIntent.setType("application/vnd.android.package-archive");
        shareIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
        ArrayList<Uri> uriFiles = new ArrayList<Uri> ();
        for(File file: files) {
            uriFiles.add (Uri.fromFile (file));
        }
        shareIntent.putParcelableArrayListExtra (Intent.EXTRA_STREAM, uriFiles);

        try {
            context.startActivity (Intent.createChooser (shareIntent, "Share via"));
        } catch (android.content.ActivityNotFoundException ex) {
            Toast.makeText (context, "There are no share applications installed.", Toast.LENGTH_SHORT).show();
        }
    }

Androidmanifest.xml:

    <?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.sample.share"
    android:versionCode="2"
    android:versionName="1.1">

    <uses-permission android:name="android.permission.WRITE_INTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

    <uses-permission android:name="ANDROID.PERMISSION.READ_EXTERNAL_STORAGE"/>

    <uses-feature
        android:glEsVersion="0x00020000"
        android:required="true" />

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name">
        <activity
            android:name="com.sample.share.SplashActivity"
            android:label="@string/app_name"
            android:theme="@style/Theme.AppCompat.Light.NoActionBar.FullScreen">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

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

        <activity
            android:name="com.sample.share.LandingScreenActivity"
            android:label="@string/app_name"
            android:theme="@style/Theme.AppCompat.Light.NoActionBar.FullScreen"/>

        <activity
            android:name="com.sample.share.MainActivity"
            android:label="@string/app_name"
            android:theme="@style/ShareToolbar"/>
    </application>

</manifest>

用于获取设备中存在的应用列表的适配器类
ShowAppsAdapter.java

public class ShowAppsAdapter extends RecyclerView.Adapter<ShowAppsAdapter.ViewHolder> implements Filterable{
    private Context context;
    private static List pkgAppsList;
    private List pkgAppsListOriginal;
    private int mLayout;
    private ArrayList<File> mFileList;
    static OnItemClickListener mItemClickListener;

    private ItemFilter filter = new ItemFilter();
    private HashMap<String,Boolean> itemChecked = new HashMap<String,Boolean>();
    private Typeface tf;

    public ShowAppsAdapter(Context context, List pkgAppsList, int layout, Typeface tf) {
        this.context = context;
        this.pkgAppsList = pkgAppsList;
        this.pkgAppsListOriginal = pkgAppsList;
        this.mLayout = layout;
        this.mFileList = new ArrayList<File> ();
        this.tf = tf;

        for (int i = 0; i < this.getItemCount (); i++) {
            itemChecked.put ((String) ((ResolveInfo) pkgAppsList.get (i)).loadLabel (context.getPackageManager ()), false); // initializes all items value with false
        }
    }

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {

        View v = LayoutInflater.from(viewGroup.getContext()).inflate(mLayout, viewGroup, false);


        return new ViewHolder(v);
    }




    @Override
    public void onBindViewHolder(final ViewHolder holder, final int position) {

        final ResolveInfo info = (ResolveInfo) pkgAppsList.get(position);
        final File file = new File(info.activityInfo.applicationInfo.publicSourceDir);
        String appSize= (Utils.getFileSize(context, info.activityInfo.applicationInfo.sourceDir));

        holder.txtAppName.setText(info.loadLabel(context.getPackageManager()));


        holder.txtAppSize.setText(/*info.activityInfo.packageName*/""+appSize);

        holder.txtAppName.setTypeface(tf);
        holder.txtAppSize.setTypeface(tf);

        holder.txtAppIcon.setImageDrawable(info.loadIcon(context.getPackageManager()));

        holder.chkTick.setChecked(itemChecked.get(info.loadLabel (context.getPackageManager ())));
        holder.chkTick.setOnClickListener (new View.OnClickListener () {
            @Override
            public void onClick (View view) {

                toggleSelected((String) info.loadLabel (context.getPackageManager ()), holder.chkTick.isChecked(),  file);

            }
        });
    }


    private void toggleSelected (String name, boolean b, File file) {
        itemChecked.put (name,b);
        if(b){
            addAppList(file);
        }else{
            removeAppList(file);
        }
    }


    private void addAppList (File file) {

        mFileList.add (file);
    }

    private void removeAppList (File file) {

        mFileList.remove (file);
    }

    public ArrayList<File> getAppList(){


        return mFileList;
    }

    @Override
    public int getItemCount() {
        return pkgAppsList == null ? 0 : pkgAppsList.size();
    }

    @Override
    public Filter getFilter () {
        return filter;
    }




    public static class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
        TextView txtAppName;
        TextView txtAppSize;
        ImageView txtAppIcon;
        CheckBox chkTick;

        public ViewHolder(View itemView) {
            super(itemView);
            txtAppName = (TextView)itemView.findViewById(R.id.text_app_name);
            txtAppSize = (TextView)itemView.findViewById(R.id.txt_app_size);
            txtAppIcon = (ImageView)itemView.findViewById(R.id.img_app_icon);
            chkTick = (CheckBox)itemView.findViewById (R.id.chk_tick);
            itemView.setOnClickListener(this);

        }



        @Override
        public void onClick(View v) {
            mItemClickListener.onItemClick(v, getAdapterPosition (),((ResolveInfo)pkgAppsList.get (getAdapterPosition ()))); //OnItemClickListener mItemClickListener;
        }

    }


    public interface OnItemClickListener {
        public void onItemClick (View view, int position, ResolveInfo o);
    }

    public void SetOnItemClickListener(final OnItemClickListener mItemClickListener) {
        this.mItemClickListener = mItemClickListener;
    }
    @Override
    public long getItemId(int i) {
        return i;
    }


    private class ItemFilter extends Filter{
        @Override
        protected FilterResults performFiltering (CharSequence charSequence) {
            String searchString = charSequence.toString ().toLowerCase ();
            FilterResults results = new FilterResults();
            final List list = pkgAppsListOriginal;

            int count = list.size();
            final List nlist = new ArrayList<ResolveInfo>(count);

            String filterableString ;

            for (int i = 0; i < count; i++) {
                final ResolveInfo info = (ResolveInfo) pkgAppsListOriginal.get(i);
                filterableString = (String) info.loadLabel (context.getPackageManager ());
                if (filterableString.toLowerCase().contains(searchString)) {
                    nlist.add(pkgAppsListOriginal.get (i));
                }
            }

            results.values = nlist;
            results.count = nlist.size();

            return results;
        }

        @Override
        protected void publishResults (CharSequence charSequence, FilterResults filterResults) {
            pkgAppsList = (List) filterResults.values;
            notifyDataSetChanged ();
        }
    }
}

推荐答案

在应用程序之间共享文件时,应该使用 FileProvider 根据 设置文件共享培训,因为这样可以确保接收应用无需任何权限即可读取文件.从 Android 6.0 开始,Gmail 不再请求存储权限,这意味着它无法读取您使用 Uri.fromFile() 提供的任何文件.

When sharing files between applications, you should use a FileProvider as per the setting up file sharing training as this ensures that the receiving app can read the file without requiring any permissions. As of Android 6.0, Gmail does not request the storage permission, meaning it is unable to read any files you provide with Uri.fromFile().

您将在清单中声明一个 FileProvider:

You'd declare a FileProvider in your manifest:

<provider
        android:name="android.support.v4.content.FileProvider"
        android:authorities="com.example.myapp.fileprovider"
        android:grantUriPermissions="true"
        android:exported="false">
        <meta-data
            android:name="android.support.FILE_PROVIDER_PATHS"
            android:resource="@xml/filepaths" />
</provider>

一个 XML 文件(在本例中称为 filepaths.xml 以匹配上述清单声明),它确定哪些目录可通过 FileProvider 获得:

An XML file (in this case called filepaths.xml to match the above manifest declaration) which determines which directories are available via the FileProvider:

<paths>
    <files-path path="images/" name="myimages" />
</paths>

然后,使用 FileProvider.getUriForFile(),传递与清单相同的权限.

Then, in place of using Uri.fromFile(file), you use FileProvider.getUriForFile(), passing in the same authority as in your manifest.

这篇关于使用 GMail app android 附加 apk 文件时权限被拒绝的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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