failed share (attach) file on android 11 - android

failed to try to share file via fileprovider, I don't know what I'm doing wrong. mistake (java.lang.IllegalArgumentException: Failed to find configured root that contains /storage/emulated/0/Download/Teste2.txt).
I tried to use the code according to the link: https: //developer.android.com/reference/androidx/core/content/FileProvider and I was not successful
in the previous versions without the fileprovider it worked perfectly using Intent.EXTRA_STREAM now in the android version 11 I was unable to make it work anymore
my code down
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:dist="http://schemas.android.com/apk/distribution"
package="com.login.projetobase">
<dist:module dist:instant="true" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme"
android:restoreNeedsApplication="true">
<!-- android.support.v4.content.FileProvider / androidx.core.content.FileProvider -->
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="com.login.projetobase.FileProvider"
android:exported="false"
android:grantUriPermissions="true" >
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="#xml/provider_paths" />
</provider>
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
<!-- GRUPO STORAGE -->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.ACCESS_MEDIA_LOCATION" />
</manifest>
provider_paths.xml
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<files-path
name="Download"
path="/" />
</paths>
MainActivity.java
public class MainActivity extends Activity {
String P_ACTIVITY = "MainActivity";
util utl = new util();
String ativa_log = "S";
File sdcard_sdk29;
private static java.io.File sdcard;
Button btn ;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btn = (Button) findViewById(R.id.btn01);
btn.setOnClickListener(new View.OnClickListener() {
#RequiresApi(api = Build.VERSION_CODES.Q)
public void onClick(View v) {
utl.PRINT_LOG(1, P_ACTIVITY+"btn.setOnClickListener-> **** INICIOU ****", ativa_log);
COMPARTILHA();
}
});
}
public void COMPARTILHA() {
try {
utl.PRINT_LOG(2, P_ACTIVITY + " COMPARTILHA() ...... INICIADO", ativa_log);
String NOME_ARQ = "Teste2.txt";
String texto = "Teste de compartilhamento";
File arq;
byte[] dados;
String RAIZ3 = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).toString();
// CRIA O ARQUIVO NA PASTA DOWNLOAD
arq = new File(RAIZ3 , NOME_ARQ);
utl.PRINT_LOG(2, P_ACTIVITY + " COMPARTILHA()-> DIRETORIO = ["+RAIZ3.toString()+"]", ativa_log);
FileOutputStream fos;
dados = texto.getBytes();
fos = new FileOutputStream(arq);
fos.write(dados);
fos.flush();
fos.close();
//INICIANDO O PROCESSO DE COMPARTILHAR AQUIVO
//Uri arquivo = Uri.fromFile(arq);
//Uri arquivo2 = Uri.parse(arq.toString());
Context context = getApplicationContext();
Uri contentUri = FileProvider.getUriForFile(context, "com.login.projetobase.FileProvider", arq);
utl.PRINT_LOG(2, P_ACTIVITY + " COMPARTILHA2()-> CAMINHO URI = ["+contentUri.toString()+"]", ativa_log);
utl.PRINT_LOG(2, P_ACTIVITY + " COMPARTILHA2()-> processando.....", ativa_log);
final Intent _intent = new Intent();
_intent.setAction(Intent.ACTION_SEND);
_intent.setType("application/pdf");
_intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION|Intent.FLAG_GRANT_READ_URI_PERMISSION);
_intent.putExtra(Intent.EXTRA_TEXT, "Compartilhamento com anexo");
_intent.putExtra(Intent.EXTRA_TITLE, "Teste de Compartilhamento");
_intent.putExtra(Intent.EXTRA_STREAM, contentUri);
startActivity(Intent.createChooser(_intent, "Compartilhar"));
} catch (Exception e) {
utl.PRINT_LOG(3, P_ACTIVITY + " ERRO->"+e, ativa_log);
Toast.makeText(getApplication(), "ERRO="+e, Toast.LENGTH_LONG).show();
}
}
}

Related

StartActivity - ActionView cannot open document - Xamarin

var storage_path = Android.OS.Environment.GetExternalStoragePublicDirectory(Android.OS.Environment.DirectoryDownloads).AbsolutePath;
filePathh = Path.Combine(storage_path, filename);
Java.IO.File file = new Java.IO.File(filePathh);
Console.WriteLine("Downloaded file PATH: " + Query.filePathh);
Intent open = new Intent(Intent.ActionView);
open.AddFlags(ActivityFlags.GrantReadUriPermission);
open.SetFlags(ActivityFlags.NewTask);
Context context = Android.App.Application.Context;
Android.Net.Uri fileUri = FileProvider.GetUriForFile(context, "com.companyname.Login.provider", file).NormalizeScheme();
Console.WriteLine("File uri: " + fileUri.Path);
open.SetDataAndType(fileUri, "*/*");
Intent intentC = Intent.CreateChooser(open, "Open With");
intentC.AddFlags(ActivityFlags.GrantReadUriPermission);
intentC.SetFlags(ActivityFlags.NewTask);
Android.App.Application.Context.StartActivity(intentC);
When trying to open a file (when choosing an app to open it - like Docs or HTML reader) we get error File Not Found.
We saw that filePathh and fileUri are different and are not pointing to the same location.
For storage_path:
storage/emulated/0/Download/How_to_initialize_your_Xamarin_app_to_use_AppConnect_C#_APIs.pdf
For Uri path:
/external/Download/How_to_initialize_your_Xamarin_app_to_use_AppConnect_C#_APIs.pdf
Do you want to achieve the result like following GIF?
I put a PDF in Download folder, I use following code to open it.
private void Button1_Click(object sender, System.EventArgs e)
{
var storage_path = Android.OS.Environment.GetExternalStoragePublicDirectory(Android.OS.Environment.DirectoryDownloads).AbsolutePath;
var filePathh = Path.Combine(storage_path, "test.pdf");
Java.IO.File file = new Java.IO.File(filePathh);
Intent open = new Intent(Intent.ActionView);
Uri photoURI = FileProvider.GetUriForFile(this, PackageName + ".provider", file);
open.SetDataAndType(photoURI, "application/pdf");
open.SetFlags(ActivityFlags.NoHistory | ActivityFlags.GrantReadUriPermission);
Intent intent = Intent.CreateChooser(open, "Open File");
try
{
StartActivity(intent);
}
catch (System.Exception)
{
throw;
}
}
Please add provider in your AndroidManifest.xml and read/write persmission.
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="1" android:versionName="1.0" package="com.companyname.app17" android:installLocation="auto">
<uses-sdk android:minSdkVersion="21" android:targetSdkVersion="28" />
<application android:allowBackup="true" android:icon="#mipmap/ic_launcher" android:label="#string/app_name" android:roundIcon="#mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="#style/AppTheme">
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="${applicationId}.provider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="#xml/provider_paths"/>
</provider>
</application>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
</manifest>
Create a xml folder in Resource folder and add following provider_paths.xml file
<?xml version="1.0" encoding="utf-8" ?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path name="external_files" path="."/>
</paths>
Here is my demo's link.
https://github.com/851265601/Xamarin.Android_ListviewSelect/blob/master/App17.zip
Please put PDF in the Download folder like following screenshot.

How can I get image Uri using File Provider?

I'm having issues with File Provider. I'm trying to get the Uri of an image I take with my phone camera. But whenever I try taking a photo, it's giving me the following error:
FATAL EXCEPTION: main Process: com.example.android.inventory, PID: 30523
java.lang.IllegalArgumentException: Failed to find configured root that contains /data/data/com.example.android.inventory/cache/IMG_20170718_213454_2102974580.jpg
at android.support.v4.content.FileProvider$SimplePathStrategy.getUriForFile(FileProvider.java:679)
at android.support.v4.content.FileProvider.getUriForFile(FileProvider.java:378)
at com.example.android.inventory.EditorActivity$5.onClick(EditorActivity.java:239)
onClickListener
//press button to take a photo
final Button addImage = (Button) findViewById(R.id.click);
addImage.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
try {
File f = createImageFile();
Log.d(LOG_TAG, "File: " + f.getAbsolutePath());
mImageUri = FileProvider.getUriForFile(
EditorActivity.this, FILE_PROVIDER_AUTHORITY, f);
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, mImageUri);
if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);
}
} catch (IOException e) {
e.printStackTrace();
}
}
});
AndroidManifest
<?xml version="1.0" encoding="utf-8"?>
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity
android:name="com.example.android.inventory.CatalogActivity"
android:label="#string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<activity
android:name="com.example.android.inventory.EditorActivity"
android:theme="#style/EditorTheme"
android:parentActivityName="com.example.android.inventory.CatalogActivity" >
<!-- Parent activity meta-data to support 4.0 and lower -->
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="com.example.android.inventory.CatalogActivity" />
</activity>
<provider
android:name="com.example.android.inventory.data.InventoryProvider"
android:authorities="com.example.android.inventory"
android:exported="false" />
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="com.example.android.myfileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="#xml/file_provider_paths" />
</provider>
</application>
<uses-feature android:name="android.hardware.camera"
android:required="true" />
File provider Path
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path name="share" path="/" />
</paths>
Any help would be appreciated. Thank you.
You can do it alternatively using Bitmap.
//The method below is opened when button is clicked you can handle in your own way
private void OpenImageChooser() {
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);
}
}
//on Activity result will give you the data when you can convert it into bitmap to show in the image view
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK) {
if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK) {
Bundle extras = data.getExtras();
Bitmap imageBitmap = (Bitmap) extras.get("data");
imgAttendance.setImageBitmap(imageBitmap);
}
}
}
In AndroidMenifest.xml
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="${applicationId}.provider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="#xml/provider_paths" />
</provider>
provider_paths.xml
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path name="external_files" path="."/>
</paths>
In OnclickListener after file create
if (Build.VERSION.SDK_INT >= 24)
mImageCaptureUri = FileProvider.getUriForFile(EditorActivity.this, BuildConfig.APPLICATION_ID + ".provider", f);
else
mImageCaptureUri = Uri.fromFile(f);
Here is code snippet to get Uri from file provider.
File imageFile = createImageFile();
picUri = FileProvider.getUriForFile(RegisterActivity.this , this.getApplicationContext().getPackageName() + ".provider", imageFile);
Below is file provider path
provider_paths.xml
file.
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path name="my_images" path="."/>
</paths>
Here <external-path> define that image save in external storage
And below shows how to define file provide in Manifest file.
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="${applicationId}.provider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="#xml/provider_paths" />
</provider>

Camera intent failing

i am using this code to run a camera intent to take a photo. All being taken from HERE step by step (full sized camera option)
private void dispatchTakePictureIntent() {
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
// Ensure that there's a camera activity to handle the intent
if (takePictureIntent.resolveActivity(getActivity().getPackageManager()) != null) {
File photoFile = null;
try {
photoFile = createImageFile();
} catch (IOException ex) {
// Error occurred while creating the File
}
// Continue only if the File was successfully created
if (photoFile != null) {
Uri photoURI = FileProvider.getUriForFile(getActivity(), "com.example.android.fileprovider", photoFile);
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI);
startActivityForResult(takePictureIntent, REQUEST_TAKE_PHOTO);
}
}
}
private File createImageFile() throws IOException {
// Create an image file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String imageFileName = "JPEG_" + timeStamp + "_";
File storageDir = getActivity().getExternalFilesDir(Environment.DIRECTORY_PICTURES);
File image = File.createTempFile(imageFileName, ".jpg",storageDir);
// Save a file: path for use with ACTION_VIEW intents
mCurrentPhotoPath = "file:" + image.getAbsolutePath();
Toast.makeText(getActivity(), mCurrentPhotoPath, Toast.LENGTH_SHORT).show();
return image;
}
This is my Manifest file:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.terrormachine.swipeapp">
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="com.example.android.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="#xml/file_paths">
</meta-data>
    </provider>
<activity
android:name=".MainActivity"
android:label="#string/app_name"
android:theme="#style/AppTheme.NoActionBar">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
and my paths xml:
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <external-path name="my_images" path="Android/data/com.example.package.name/files/Pictures" />
</paths>
and i am getting this error:
java.lang.IllegalArgumentException: Failed to find configured root that contains /storage/emulated/0/Android/data/com.example.terrormachine.swipeapp/files/Pictures/JPEG_20161015_211933_-593154643.jpg
A little surprising since the file "shell" is there(at this location).
I fount THIS thread but i cant understand a thing...can you explain it humanlike? Any solution is welcome! Its an important project and i need to finish as much as possible and this is a huge stop.
In your files_path.xml, you need to replace com.example.package.name with your apps package name, as explained on developers site.
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path name="my_images" path="Android/data/com.example.terrormachine.swipeapp/files/Pictures" />
</paths>
Also add camera permission in your AndroidManifest.xml file.
<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera"
android:required="true" />
I think you are missing "uses-feature android:name="android.hardware.camera" android:required="true"" in your manifest.

FileNotFoundException - Android - Creating and saving a pdf file to external storage

I have a problem in my android app while trying to create a pdf file from view of app.
W/System.err: java.io.FileNotFoundException: /storage/emulated/0/Documents/MyList/MyList.pdf: open failed: ENOENT (No such file or directory)
I had an error such like above. What am I missing there?
How can I handle it? Can you help me? Thanks.
Here is the Manifest file of my project.
<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.furkan.tercihrehberi">
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:supportsRtl="true"
android:theme="#style/AppTheme.NoActionBar">
<!--activities...-->
<activity
android:name=".ListeMyo"
android:label="#string/app_name">
</activity>
<activity
android:name=".PDFGoster"
android:label="#string/app_name">
<intent-filter >
<action android:name="android.intent.action.OPEN_DOCUMENT" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
<activity
android:name=".PDFGosterTeog"
android:label="#string/app_name">
<intent-filter >
<action android:name="android.intent.action.OPEN_DOCUMENT" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
</application>
ImageButton save = (ImageButton) findViewById(R.id.save);
save.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String state = Environment.getExternalStorageState();
if (!Environment.MEDIA_MOUNTED.equals(state)) {
Toast.makeText(PDFGoster.this,"You cannot do that.",Toast.LENGTH_LONG).show();
}
File pdfDir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS),
"MyList");
if (!pdfDir.exists()){
pdfDir.mkdir();
}
LayoutInflater inflater = (LayoutInflater) PDFGoster.this.getSystemService(LAYOUT_INFLATER_SERVICE);
RelativeLayout root = (RelativeLayout) inflater.inflate(R.layout.pdf, null);
root.setDrawingCacheEnabled(true);
Bitmap screen= getBitmapFromView(PDFGoster.this.getWindow().findViewById(R.id.tabla_cuerpo));
File pdfFile = new File(pdfDir, "MyList.pdf");
try {
Document document = new Document();
PdfWriter.getInstance(document, new FileOutputStream(pdfFile));
document.open();
ByteArrayOutputStream stream = new ByteArrayOutputStream();
screen.compress(Bitmap.CompressFormat.PNG, 100, stream);
byte[] byteArray = stream.toByteArray();
addImage(document,byteArray);
document.close();
}
catch (Exception e){
e.printStackTrace();
}
Intent intent = new Intent("android.intent.action.OPEN_DOCUMENT");
Uri uri = Uri.fromFile(new File(pdfDir, "MyList"));
intent.setDataAndType(uri, "application/pdf");
intent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
Toast.makeText(PDFGoster.this, "List successfully created", Toast.LENGTH_LONG).show();
startActivity(intent);
}
});

Intent Filter not working for Android Beam NFC

I am sure this is simple but I cannot figure it out. All I am trying to do is send a message via NFC (android Beam) and open my App on the receiver device. I did test my code on a new Project and it worked perfectly but if I try it on my real Project it just start "New Tag collected" and shows application/eu.freemoser.mydebts2go (see my screenshot). I don't know what's wrong maybe something with the manifest? The Google results doesn't match with my problem (or I am just to stupid) but I believe I found some related answer unfortunately I still was not able to solve my problem
My Manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="eu.freemoser.myDebts2go"
android:versionCode="16"
android:versionName="1.1.0">
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.READ_CONTACTS" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.NFC" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="com.android.launcher.permission.UNINSTALL_SHORTCUT" />
<uses-permission android:name="com.android.launcher.permission.INSTALL_SHORTCUT" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES" />
<uses-permission android:name="com.android.alarm.permission.SET_ALARM" />
<uses-feature android:name="android.hardware.nfc" android:required="false" />
<uses-feature android:name="android.hardware.camera" />
<uses-sdk
android:minSdkVersion="16"
android:targetSdkVersion="19" />
<uses-feature
android:glEsVersion="0x00020000"
android:required="true" />
<application
android:name="eu.freemoser.myDebts2go.MyApplication"
android:allowBackup="true"
android:hardwareAccelerated="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/Theme.Mydebts2go">
>
<service android:name="eu.freemoser.myDebts2goService.NotificationService"></service>
<service android:name="eu.freemoser.myDebts2goService.SynchronizationService"></service>
<service android:name="eu.freemoser.myDebts2goService.SynchronizService"></service>
<service android:name="eu.freemoser.myDebts2goService.AwesomeSynchronizService"></service>
<activity
android:name="eu.freemoser.myDebts2go.MainActivity"
android:label="#string/app_name"
android:screenOrientation="portrait">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name="eu.freemoser.myDebts2GoActivities.AwesomeDetailActivity"
android:screenOrientation="portrait" android:theme="#style/Theme.MyDebts2GO.Detail">
</activity>
<activity android:name=".AndroidBeamActivity" android:screenOrientation="portrait"
android:theme="#android:style/Theme.DeviceDefault.Wallpaper.NoTitleBar">
<intent-filter>
<action android:name="android.nfc.action.NDEF_DISCOVERED" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="application/eu.freemoser.myDebts2go" />
</intent-filter>
</activity>
<activity android:name="eu.freemoser.myDebts2GoActivities.DriveRestoreActivity"></activity>
<activity android:name="eu.freemoser.myDebts2GoActivities.SynchronizActivity"></activity>
<activity android:name="eu.freemoser.myDebts2GoActivities.SettingActivity">
<intent-filter>
<action android:name="android.intent.action.MANAGE_NETWORK_USAGE" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
<activity android:name="eu.freemoser.myDebts2GoActivities.DatePickerActivity"></activity>
<activity android:name="eu.freemoser.myDebts2GoActivities.LocationPickerActivity"></activity>
<activity android:name="eu.freemoser.myDebts2GoActivities.SearchActivity">
<intent-filter>
<action android:name="android.intent.action.SEARCH" />
</intent-filter>
</activity>
<activity
android:name="eu.freemoser.myDebts2GoActivities.DriveAuthorzingActivity"
android:theme="#android:style/Theme.Translucent.NoTitleBar">
</activity>
<activity
android:name="eu.freemoser.myDebts2GoActivities.FastModusShortcutActivity"
android:exported="true"
android:theme="#android:style/Theme.Holo.Light.NoActionBar">
</activity>
<!-- android:value="API_KEY" /> DEBUG-->
<meta-data
android:name="com.google.android.maps.v2.API_KEY"
android:value="API_KEY" />
<meta-data
android:name="com.google.android.gms.version"
android:value="VERSION" />
</application>
</manifest>
The Fragment (sender)
public class AwesomeDetailFragment extends Fragment implements ObservableScrollView.Callbacks, NfcAdapter.CreateNdefMessageCallback, NfcAdapter.OnNdefPushCompleteCallback {
...
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
...
setUpAndroidBeam();
return mRootView;
}
private void setUpAndroidBeam() {
PackageManager pm = getActivity().getPackageManager();
// Check whether NFC is available on device
if (!pm.hasSystemFeature(PackageManager.FEATURE_NFC)) {
// NFC is not available on the device.
}
// Check whether device is running Android 4.1 or higher
else if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
// Android Beam feature is not supported.
} else {
myNfcAdapter = NfcAdapter.getDefaultAdapter(getActivity());
manageNfc();
}
}
private void manageNfc() {
if (myNfcAdapter != null) {
myNfcAdapter.setNdefPushMessageCallback(this, getActivity());
myNfcAdapter.setOnNdefPushCompleteCallback(this, getActivity());
}
}
...
#Override
public NdefMessage createNdefMessage(NfcEvent event) {
Time time = new Time();
time.setToNow();
String text = myBetrag + "//" + myTitle + "//" + myContactName + "//" + myStatus + "//" + myDebtDate + "//" + myCreateDate + "//" + myRemamberDate + "//" + myNote;
NdefMessage msg = new NdefMessage(
new NdefRecord[]{createMimeRecord(
"application/eu.freemoser.myDebts2go", text.getBytes())});
return msg;
}
public NdefRecord createMimeRecord(String mimeType, byte[] payload) {
byte[] mimeBytes = mimeType.getBytes(Charset.forName("US-ASCII"));
NdefRecord mimeRecord = new NdefRecord(
NdefRecord.TNF_MIME_MEDIA, mimeBytes, new byte[0], payload);
return mimeRecord;
}
#Override
public void onNdefPushComplete(NfcEvent event) {
}
}
The Activity (receiver)
public class Beam extends Activity {
private Long userID = null;
private Long adressID = null;
private DBAdapter myDb;
//NFC
private String myBetrag;
private String myTitle;
private String myContactName;
private String myDebtDate;
private String myCreateDate;
private String myStatus;
private String myRemamberDate;
private String myNote;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
protected void onResume() {
super.onResume();
if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(getIntent().getAction())) {
processIntent(getIntent());
}
}
void processIntent(Intent intent) {
myDb = new DBAdapter(this);
myDb.open();
Parcelable[] rawMsgs = intent.getParcelableArrayExtra(
NfcAdapter.EXTRA_NDEF_MESSAGES);
// only one message sent during the beam
NdefMessage msg = (NdefMessage) rawMsgs[0];
// record 0 contains the MIME type, record 1 is the AAR, if present
String temp = new String(msg.getRecords()[0].getPayload());
String[] arrrayTemp = temp.split("//");
try {
myBetrag = arrrayTemp[0];
myTitle = arrrayTemp[1];
myContactName = arrrayTemp[2];
myStatus = arrrayTemp[3];
myDebtDate = arrrayTemp[4];
myCreateDate = arrrayTemp[5];
// can be "NOT"
myRemamberDate = arrrayTemp[6];
myNote = arrrayTemp[7];
// checkValues
channgeStatus();
checkIfNot();
checkUser();
//write to database
write();
} catch (Exception ex) {
this.finish();
}
}
#Override
protected void onDestroy() {
super.onDestroy();
myDb.close();
}
private void checkUser() {
//do some stuff
...
}
private void write() {
//do some stuff
...
}
private void checkIfNot() {
//do some stuff
...
}
private void channgeStatus() {
//do some stuff
...
}
#Override
public void onNewIntent(Intent intent) {
// onResume gets called after this to handle the intent
setIntent(intent);
}
}
Android's MIME type matching for intent filters is case-sensitive (eventhough the MIME types themselves are not). Therefore, with Android (and also pretty much everywhere you use them) you should stick to the convention to use MIME types with lowercase letters only.
Specifically with MIME type records received over NFC, Android will automatically convert them to all-lowercase letters to overcome the problem of case-sensitivity in intent filters. So in your example, changing the type name in the intent filter to "application/eu.freemoser.mydebts2go" should work:
<intent-filter>
<action android:name="android.nfc.action.NDEF_DISCOVERED"/>
<category android:name="android.intent.category.DEFAULT"/>
<data android:mimeType="application/eu.freemoser.mydebts2go"/>
</intent-filter>
In addition, you should also make sure you send the MIME type in lowercase letters only:
NdefMessage msg = new NdefMessage(
new NdefRecord[]{createMimeRecord(
"application/eu.freemoser.mydebts2go", text.getBytes())});

Categories

Resources