Tweet Compose OR Sharing Image On Twitter Using Fabric - android

I am following this tutorial to share tweet + image on twitter.
https://docs.fabric.io/android/twitter/compose-tweets.html
Its working perfectly to share text on twitter with success and failure response but i am not able to share image, any one guide me what mistake i am doing here?
Note: when i share image from drawable folder of app it uploads, but i have to download image from Internet and then save it on internal storage.
My commented code below of explains clearly that image is being saved on internal storage as i tested it.
public void composetweet()
{
File myDir = getFilesDir();
File savedImage = new File(myDir + "/text/","test.jpg");
/* if(savedImage.exists()){
Bitmap myBitmap = BitmapFactory.decodeFile(savedImage.getAbsolutePath());
ImageView myTestImage = (ImageView) findViewById(R.id.myimageview);
myTestImage.setImageBitmap(myBitmap);
}*/
Uri myImageUri = Uri.fromFile(savedImage);
Intent intent = new TweetComposer.Builder(this)
.text("just setting up my Fabric.")
.image(myImageUri)
.createIntent();
startActivityForResult(intent, TWEET_COMPOSER_REQUEST_CODE);
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(requestCode == TWEET_COMPOSER_REQUEST_CODE) {
if(resultCode == Activity.RESULT_OK) {
// onTwitterSuccess();
} else if(resultCode == Activity.RESULT_CANCELED) {
// onTwitterCancel();
}
}
}
I have also tried:
Uri myImageUri = Uri.fromFile(savedImage);
TweetComposer.Builder builder = new TweetComposer.Builder(this)
.text("just setting up my Fabric.")
.image(myImageUri);
builder.show();
But no luck.
Any ideas?

After doing some research i found:
when you are saving data on internal storage from your app and try to pickup inside same app it will work.
But if you want to share that file created from your app in another app, internal storage will not give you permissions.
Hence i followed this solution to make that work:
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="com.mobitsolutions.socialmediashare.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="#xml/pathfile"/>
</provider>

The image Uri should be a file Uri (i.e. file://absolute_path scheme) to a local file. For example:
File myImageFile = new File("/path/to/image");
Uri myImageUri = Uri.fromFile(myImageFile);
try to retrive image path with absolutepath also ther is one other option setting Twittercard.
https://dev.twitter.com/cards/types/app

Related

Unable to open captured photo in Android's default image viewer using photo's URI

One of the features of my app is to allow user to assign a photo of an item stored in a DB. This could be done by either taking a new photo with the in-built camera or choosing an image from the library. Then app resizes the captured image, retrieve a full size image URI and store both in a DB. Full size image URI is stored for a later use in case user wants to load a full size image with the default image viewer. Everything works fine except viewer is unable to load image from the captured image URI right after the photo is taken, but it is possible to load the same image only when it is chosen from the library.
Ok here is the code:
manifest:
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="com.packagename.inventoryapp.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="#xml/fileprovider" />
</provider>
fileprovider.xml
<external-files-path
name="images"
path="Pictures" />
Handle the camera:
#NeedsPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE)
public void onLaunchCamera(){
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
photoFileName = String.valueOf(System.currentTimeMillis()) + ".jpg";
photoFile = getPhotoFileUri(photoFileName);
Uri fileProvider = FileProvider.getUriForFile(this,
ProductContract.CONTENT_AUTHORITY + ".fileprovider", photoFile);
intent.putExtra(MediaStore.EXTRA_OUTPUT, fileProvider);
if (intent.resolveActivity(getPackageManager()) != null) {
startActivityForResult(intent, CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE);
}
}
public File getPhotoFileUri(String fileName){
File mediaStorageDir = new File(getExternalFilesDir(Environment.DIRECTORY_PICTURES), APP_TAG);
if (!mediaStorageDir.exists() && !mediaStorageDir.mkdirs()){
Log.d(APP_TAG, "failed to create directory");
}
return new File(mediaStorageDir.getPath() + File.separator + fileName);
}
onActivtiyResult (takenImage - global Bitmap variable;
mPicUri - global Uri variable):
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
/* User chose to take a new photo */
if (requestCode == CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE) {
if (resultCode == RESULT_OK) {
File takenPhotoUri = getPhotoFileUri(photoFileName);
mPicUri = FileProvider.getUriForFile
(this, ProductContract.CONTENT_AUTHORITY + ".fileprovider", photoFile);
Bitmap fullSizeImage = BitmapFactory.decodeFile(takenPhotoUri.getAbsolutePath());
takenImage = BitmapScaler.scaleToFitWidth
(fullSizeImage, mProductImageView.getWidth() / 100 * 50);
} else { // Result was a failure
Toast.makeText(this, getString(R.string.no_picture_taken),
Toast.LENGTH_SHORT).show();
}
}
/* User chose to take an an existing photo from the gallery */
else if (requestCode == PICK_PHOTO_CODE){
if (resultCode == RESULT_OK) {
mPicUri = data.getData();
try {
Bitmap fullSizeImage = MediaStore.Images.Media.getBitmap
(getContentResolver(), mPicUri);
takenImage = BitmapScaler.scaleToFitWidth
(fullSizeImage, mProductImageView.getWidth() / 100 * 60);
} catch (IOException e) {
e.printStackTrace();
}
}
}
mProductImageView.setImageBitmap(takenImage);
/* Save image and it's URi to the database */
if (takenImage != null){
ContentValues values = new ContentValues();
values.put(ProductEntry.COLUMN_IMAGE, DbBitmapUtility.getBytesArray(takenImage));
values.put(ProductEntry.COLUMN_IMAGE_URL, mPicUri.toString());
int rows = getContentResolver().update(mProductUri, values, null, null);
}
}
Open default image image viewer to load a full size image from Uri:
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(mPicUri);
startActivity(intent);
I realise that the problem is in Uri path of a captured photo. When I retrieve it in the above way I get something like:
content://com.packagename.inventoryapp.fileprovider/images/InventoryApp/1526632674426.jpg
and Image viewer is launching with the blank screen indicating it is searching for the image with no success.
I tried to get mPicUri with getAbsolutePath() method that leads to the app crashing on launching the intent with that message:
android.content.ActivityNotFoundException: No Activity found to handle Intent { act=android.intent.action.VIEW dat=/storage/emulated/0/Android/data/com.packagename.inventoryapp/files/Pictures/InventoryApp/1526635391354.jpg }
On the contrary taking image from the existing library works fine and image Uri looks like:
content://com.google.android.apps.photos.contentprovider/0/1/content%3A%2F%2Fmedia%2Fexternal%2Fimages%2Fmedia%2F2504/ORIGINAL/NONE/1872082740
So the question is it possible to somehow retrieve captured image Uri that is not app private and could be red by image viewer?
android.content.ActivityNotFoundException: No Activity found to handle Intent { act=android.intent.action.VIEW dat=/storage/emulated/0/Android/data/com.packagename.inventoryapp/files/Pictures/InventoryApp/1526635391354.jpg }
That is not a valid Uri.
A Uri has a scheme. Yours does not. Yours resembles a bare filesystem path. In principle, you could convert that to a Uri using Uri.fromFile().
However, on Android 7.0+, using such a Uri will fail with a FileUriExposedException.
Instead, use the File with FileProvider.getUriForFile(), and provide that Uri to your ACTION_VIEW Intent. Be sure to also call addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION) on that Intent, to allow third-party apps to read the content identified by that Uri.

How to convert content:// to file after image capture android?

I am capturing image using camera in android using the following code snippet.
Intent imageIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
fileUri = getOutputMediaFileUri(Constants.ATTACH_IMAGE);
imageIntent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);
imageIntent.putExtra("outputFormat",Bitmap.CompressFormat.JPEG.toString());startActivityForResult(imageIntent, Constants.ATTACH_IMAGE);
in onActivityResult, I want to convert the "content://" uri back to File, compress it and show a thumb nail.
How can I do it?
Edit :-
What I have tried:-
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
Log.d("activity result","coming" + String.valueOf(requestCode)+ contentFileUri);
// View popupView = getActivity().getLayoutInflater().inflate(R.layout.popup_add_snag, null);
// LinearLayout attachLayout = (LinearLayout)popupView.findViewById(R.id.attachLayout);
// ImageView photoImageicon = (ImageView)popupView.findViewById(R.id.imageicon);
try{
// if (resultCode == Constants.RESULT_OK){
if(contentFileUri !=null) {
Log.d("fileuri", contentFileUri.toString());
String attachmentType = "IMAGE";
// mAdapter.attachmentType=attachmentType;
photoImageIcon.setVisibility(View.VISIBLE);
// attachLayout.setVisibility(View.INVISIBLE);
Toast.makeText(getActivity().getApplicationContext(), R.string.successfull_image, Toast.LENGTH_SHORT).show();
Log.d("fileuri", contentFileUri.toString());
InputStream inputStream = getContext().getContentResolver().openInputStream(contentFileUri);
contentFileUri looks like this:- "content://com.fa.ha.provider/external_files/F/7c7.jpeg"
But above results in "FileNotFound Exception, not a directory" at the last line.
Ideally, just hang onto the File that getOutputMediaFileUri() is creating. Hopefully, getOutputMediaFileUri() is setting up a FileProvider Uri for you, based off of a File, so if you hold onto the File, you do not need to worry about "converting" anything. See this sample app.
If getOutputMediaFileUri() is poorly written, perhaps you do not have a File. In that case, in onActivityResult(), you can pass the Uri to an image-loading library (Picasso, Glide, etc.) and have it populate an ImageView or simply load the Bitmap for you.

filedescriptor use to render pdf file from external storage in android

I have downloaded a pdf file in external storage directory and i want to reder it using pdfrender in android.
i have successfully rendered the pdf saved in my asset folder but now i need to render the file that is saved in external directory. here is the code i am using
String filePath1 = Environment.getExternalStorageDirectory().toString()+"/Mock-up Presentation.pdf";
//filePath1 is the location for file i want to render
File file = new File(filePath1);
mFileDescriptor=getActivity().getAssets().openFd("sample.pdf").getParcelFileDescriptor();//sample pdf is saved in asset folder in project which i have rendered //already
// This is the PdfRenderer we use to render the PDF.
mPdfRenderer = new PdfRenderer(mFileDescriptor);
Any help would be appreciated.
If you faced this problem in project that is targeting android 9+,
Get Complete Code For Solution.from Here
Then you can follow some Steps:
Step 1: Open an Intent for selecting PDF file.
/This Code will help to open Intent../
public final int PDF_REQUEST_CODE =1200;
Intent intent=new Intent();
intent.setAction(Intent.ACTION_OPEN_DOCUMENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.setType("application/pdf");
startActivityForResult(intent,PDF_REQUEST_CODE);
Step 2: now catch result returned by above intent.
protected void onActivityResult(int requestCode, int resultCode, #Nullable Intent data)
{
super.onActivityResult(requestCode, resultCode, data);
if(requestCode==PDF_REQUEST_CODE && resultCode == Activity.RESULT_OK)
{
Uri uri=data.getData();
PdfRendererBasicViewModel pdfRendererBasicViewModel =new
ViewModelProvider(this).get(PdfRendererBasicViewModel.class);
pdfRendererBasicViewModel.setUri(uri);
getSupportFragmentManager().beginTransaction()
.add(R.id.container, new PdfRendererBasicFragment())
.commitNow();
}
}
Step 3: Need some Modifications on pdfRendererBasicViewModel class.
First of all need to declare methods that set/get file's Uri in viewmodel.
as we called setUri(). in onActivityResult() method.
After That update replace openPdfRenderer() method with
private static Uri uri; `
private void openPdfRenderer() throws IOException {
if(getUri()!=null){
mFileDescriptor =
getApplication().getContentResolver().openFileDescriptor(getUri(), "r");
}
if (mFileDescriptor != null) {
mPdfRenderer = new PdfRenderer(mFileDescriptor);
}
}`
now try to run ...
If You want a complete Solution then you can import from github here

How to change the directory of SquareCamera library?

I am using SquareCamera library (https://github.com/boxme/SquareCamera) for taking square picture.The problem I am facing is that SquareCamera is creating its own folder where taken pics are getting stored. I want these pics to store in my own folder. I don't know how to achieve that. I am very new to android. Below is the code where instead of default camera I am calling its own class.
public void onLaunchCamera(View view) {
// create Intent to take a picture and return control to the calling application
Intent intent = new Intent(this,CameraActivity.class);
// Start the image capture intent to take photo
startActivityForResult(intent, CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE);
And this is the onActivityResult method
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE) {
if (resultCode == RESULT_OK) {
Uri takenPhotoUri = data.getData();
Bitmap takenImage = BitmapFactory.decodeFile(takenPhotoUri.getPath());
imageView.setImageBitmap(takenImage);
I thought about saving this bitmap into my own folder but I couldn't think how to delete the created directory of SquareCamera.
So I found the solution. I added the library as a module in my app. Referring (https://www.youtube.com/watch?v=1MyBO9z7ojk). And there I changed the source code a little bit and now it's working perfect.
I'm a bit long in the tooth at Android and am not 100% with the new Uri methods of file access enforced since KitKat. For conventional file access you can get a private writeable file using.
private static final File OUTPUT_DIR = Environment.getExternalStorageDirectory();
FileOutputStream fos;
void yourMethodBeginsHere() {
String outputPath = new File(OUTPUT_DIR, "test.png").toString();
try {
fos = new FileOutputStream(outputPath, false);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
//Work with file
}
If you need a truly external file path please refer to the excellent answer already existing at https://stackoverflow.com/a/26765884/5353361 which deals fully with the new Uri based system of permissions and the integrated file explorer.

Can't save a photo to external storage using getFilesDir()

I'm trying to save a photo to external storage and display it in a ImageView, but I don't want other apps can access this photo. I try to create a new File with the method getFilesDir() as the directory argument when I want to create that file, but if I ask if I can write to it (to save the image), it return that I can't (see the code for more details).
Note that the app has the android.permission.WRITE_EXTERNAL_STORAGE permission.
public void takePhoto(View v) {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
File file = new File(getFilesDir(), "my_image.jpg");
// Check if I can write in this path (I always get that I can't)
if (file.canWrite()) {
Toast.makeText(this, "I can write!", Toast.LENGTH_LONG).show();
} else {
Toast.makeText(this, "I CAN'T WRITE!", Toast.LENGTH_LONG).show();
}
intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(file));
startActivityForResult(intent, IMAGE_REQUEST_CODE);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == IMAGE_REQUEST_CODE) {
File file = new File(getFilesDir(), "my_image.jpg");
Bitmap bitmap = decodeSampledBitmapFromFile(file.getAbsolutePath(), 1000, 700);
imageView.setImageBitmap(bitmap);
}
}
However, if I use the Environment.getExternalStorageDirectory() method, I'm able to save the photo.
I think I might be misunderstanding anything about how File works, but I don't know exactly what. I have no FC, the image just doesn't show in the ImageView.
If you save to an external storage everyone will see the image :
Here's External Storage!
Then when you receive the callback onActivityResult you will receive the URI from the image
Uri mUriFile = data.getData()
Then depending on the OS version you can get the file path
HereĀ“s a good post to get it Android Gallery on KitKat returns different Uri for Intent.ACTION_GET_CONTENT

Categories

Resources