Permisssion在附加GMail app android的apk文件时被拒绝 [英] Permisssion denied while attaching apk file with GMail app android

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

问题描述

我有要求通过共享意图发送apk文件,我也没有任何麻烦实施。但问题只在通过GMail发送apk时发生,我在尝试附加时拒绝权限。我真的不知道GMail发生了什么。请帮助我解决您的问题和解决方案。任何小提示和技巧对我来说也是有用的。在此先感谢

我使用以下代码来使用共享意图发送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> (); (文件file:files)
{
uriFiles.add(Uri.fromFile(file));
}
shareIntent.putParcelableArrayListExtra(Intent.EXTRA_STREAM,uriFiles);

尝试{
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.0encoding =utf-8?> 
< manifest xmlns:android =http://schemas.android.com/apk/res/android
package =com.sample.share
android:versionCode = 2
android:versionName =1.1>

<使用权限android:name =android.permission.WRITE_INTERNAL_STORAGE/>
< uses-permission android:name =android.permission.WRITE_EXTERNAL_STORAGE/>

<使用权限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>

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

android:name =com.sample.share.LandingScreenActivity
android:label =@ string / app_name
android:theme = @风格/ Theme.AppCompat.Light.NoActionBar.FullScreen/>

android:name =com.sample.share.MainActivity
android:label =@ string / app_name
android:theme = @风格/ ShareToolbar/>
< / application>

< / manifest>

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

  public class ShowAppsAdapter extends RecyclerView.Adapter< ShowAppsAdapter.ViewHolder> ;实现可过滤{
private上下文;
private static List pkgAppsList;
私人列表pkgAppsListOriginal;
private int mLayout;
private ArrayList< File> mFileList;
static OnItemClickListener mItemClickListener;

private ItemFilter filter = new ItemFilter();
私有HashMap< String,Boolean> itemChecked = new HashMap< String,Boolean>();
私人字体tf;

public ShowAppsAdapter(Context context,List pkgAppsList,int layout,Type tf){
this.context = context;
this.pkgAppsList = pkgAppsList;
this.pkgAppsListOriginal = pkgAppsList;
this.mLayout = layout;
this.mFileList = new ArrayList< File> ();
this.tf = tf; (int i = 0; i< this.getItemCount(); i ++){
itemChecked.put((String)((ResolveInfo)pkgAppsList.get(i))的

。 loadLabel(context.getPackageManager()),false); //使用false
}
初始化所有项目的值
$ b @覆盖
public ViewHolder onCreateViewHolder(ViewGroup viewGroup,int i){

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


返回新的ViewHolder(v);




$ b @Override
public void onBindViewHolder(final ViewHolder持有者,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);

}
});


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



$ b private void addAppList(File file){

mFileList.add(file);
}

private void removeAppList(文件文件){

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;




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

public ViewHolder(查看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;


$ b private class ItemFilter extends Filter {
@Override
FilterResults performFiltering(CharSequence charSequence){
String searchString = charSequence。 toString().toLowerCase();
FilterResults results = new FilterResults();
final列表= pkgAppsListOriginal;

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

字符串filterableString; (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();

返回结果;

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




解决方案

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



您将在清单中声明一个 FileProvider

 < 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 来匹配上面的manifest声明),它通过 FileProvider 确定哪些目录是可用的:

 <路径> 
< files-path path =images /name =myimages/>
< /路径>

然后,代替使用 Uri.fromFile(file),你可以使用 FileProvider.getUriForFile() ,传入与清单相同的权限。 p>

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

I am using following code to send APK using shared intents:

 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>

Adapter class to fetch the list of apps present in the device
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 ();
        }
    }
}

解决方案

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().

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>

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>

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

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

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