I've an Android App, which works fine in Jelly Bean and Kitkat versions. The app will receive .vcf file as Intent
from File Manager app using Complete Action Using option.
Now in Android Nougat and Oreo versions, Using Files app, there is an option Open with or Share will not list my App.
How to solve this? Thanks in advance.
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.app" >
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.READ_CONTACTS" />
<uses-permission android:name="android.permission.WRITE_CONTACTS" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme.CustomOrange"
>
<activity>
...
...
</activity>
<activity
android:name=".ViewContactActivity"
android:configChanges="orientation|keyboardHidden|screenSize"
android:label="@string/title_activity_vcf" >
<intent-filter> <!-- Handle http https requests without mimeTypes: -->
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.BROWSABLE" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="http" />
<data android:scheme="https" />
<data android:host="*" />
<data android:pathPattern="/.*\\.vcf" />
</intent-filter>
<intent-filter> <!-- Handle with mimeTypes, where the suffix is irrelevant: -->
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.BROWSABLE" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="http" />
<data android:scheme="https" />
<data android:host="*" />
<data android:mimeType="text/x-vcard" />
</intent-filter>
<intent-filter> <!-- Handle intent from a file browser app: -->
<action android:name="android.intent.action.VIEW" />
<action android:name="android.intent.action.INSERT_OR_EDIT" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="file" />
<data android:host="*" />
<data android:mimeType="text/x-vcard" />
</intent-filter>
</activity>
</application>
</manifest>
ViewContactActivity.java
public class ViewContactActivity
extends AppCompatActivity {
private static final String TAG = ViewContactActivity.class.getSimpleName();
public static final String VIEW_CONTACT_BY_ID = "viewContactById";
private static final int MODE_VIEW_BY_ID = 0;
private static final int MODE_VIEW_BY_FILE = 1;
private int viewContactMode;
private ActionBar mActionBar;
ContactDetails contactDetails;
String mFilePath;
private GroupInfoPickerAlertDialog mGroupInfoPickerAD;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_vcf);
contactDetails = new ContactDetails(this);
Intent intent = getIntent();
Long id = intent.getLongExtra(VIEW_CONTACT_BY_ID, -1L);
Bitmap bitmap = null;
if (id != -1L) {
viewContactMode = MODE_VIEW_BY_ID;
contactDetails.collectContactDetail(id);
bitmap = BitmapFactory.decodeStream(new BufferedInputStream(contactDetails.getDisplayPhoto()));
} else {
viewContactMode = MODE_VIEW_BY_FILE;
Uri fileUri = intent.getData();
mFilePath = fileUri.getPath();
Log.d(TAG, "onCreate() - file path: " + mFilePath);
//onCreate() - file path: /path/to/file.vcf
contactDetails.readVCard2_1(fileUri);
}
setSupportActionBar((Toolbar)findViewById(R.id.toolbar));
mActionBar = getSupportActionBar();
if(mActionBar == null) {
Log.d(TAG, "onCreate() mActionBar == null");
} else {
Log.d(TAG, "onCreate() mActionBar != null");
}
mActionBar.setCustomView(null);
mActionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_HOME | ActionBar.DISPLAY_SHOW_TITLE);
contactDetails.displayContact(bitmap);
if (viewContactMode == MODE_VIEW_BY_FILE) {
TextView textView = (TextView) findViewById(R.id.message_text_view);
textView.setText(mFilePath);// + "\n\n" + stringBuilder);
} else {
View v = (View) findViewById(R.id.message_text_view).getParent();
v.setVisibility(View.GONE);
}
}
// ....
// ....
// Other codes...
// ....
// ....
}
Your <intent-filter>
elements support http
, https
, and file
. Few "file manager" apps will use any of those on Android 7.0+, in part because the file
scheme is banned.
Replace:
<intent-filter> <!-- Handle intent from a file browser app: -->
<action android:name="android.intent.action.VIEW" />
<action android:name="android.intent.action.INSERT_OR_EDIT" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="file" />
<data android:host="*" />
<data android:mimeType="text/x-vcard" />
</intent-filter>
with:
<intent-filter> <!-- Handle intent from a file browser app: -->
<action android:name="android.intent.action.VIEW" />
<action android:name="android.intent.action.INSERT_OR_EDIT" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="file" />
<data android:scheme="content" />
<data android:mimeType="text/x-vcard" />
</intent-filter>
Then, make sure that readVCard2_1()
handles file
and content
Uri
schemes, such as by calling openInputStream()
on a ContentResolver
to access the stream.