I use Fabric SDK to send tweets from my application.
I build a share dialog and send tweet from activity.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
TwitterAuthConfig authConfig = new TwitterAuthConfig(CONSUMER_KEY, CONSUMER_SECRET);
Fabric.with(this, new TwitterCore(authConfig), new TweetComposer());
Bundle bundle = getIntent().getExtras().getBundle(SHARE_DATA);
String description = bundle.getString(SHARE_DESCRIPTION);
String title = bundle.getString(SHARE_TITLE);
String picture = bundle.getString(SHARE_PICTURE_LINK);
String link = bundle.getString(SHARE_LINK);
TweetComposer.Builder builder = null;
try {
InputStream in = new java.net.URL(picture).openStream();
Bitmap bitmap = BitmapFactory.decodeStream(in);
Uri yourUri = getImageUri(this,bitmap);
builder = new TweetComposer.Builder(this)
.text(title + "\n" + description)
.url(new URL(link))
.image(yourUri);
//??? IS THERE ANY LISTENER ???
builder.show();
} catch (IOException e1) {
e1.printStackTrace();
}
}
I want to know status of sharing, like an success or not, but i can't find any listener for this action. I missed something?
Instead of use builder.show(), you should use builder.createIntent() :
Intent intent = new TweetComposer.Builder(getActivity())
.text("TEXT")
.url("URL")
.createIntent();
startActivityForResult(intent, TWEET_COMPOSER_REQUEST_CODE);
To get the result feedback in onActivityResult() :
#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();
}
}
}
use below method to twitt via rest service and pass media id as null.i m successfully posting tweets from my app
public void postToTwitter(ArrayList<String>mediaIds) {
String message;
if(Validator.isNotNull(preferences.getFbShareMessage())){
message=preferences.getFbShareMessage()+" "+com.aimdek.healthwel.network.Request.HOST_URL + "/user-history/" + userHistory.getUserId() + "/" + userHistory.getId();
}
else {
message = getString(R.string.google_status, HWUtil.getFullName(preferences.getUserInfo().getFirstName(), preferences.getUserInfo().getLastName()), userHistory.getSportName(), HWUtil.secondToTime(userHistory.getDuration()))+" "+com.aimdek.healthwel.network.Request.HOST_URL + "/user-history/" + userHistory.getUserId() + "/" + userHistory.getId();
}
String mediaId;
if (Validator.isNotNull(mediaIds) && mediaIds.size() > 0) {
mediaId="";
for (int i = 0; i < mediaIds.size(); i++) {
if (i == 0) {
mediaId = mediaIds.get(i);
} else {
mediaId += "," + mediaIds.get(i);
}
}
}
else {
mediaId=null;
}
StatusesService statusesService = twitterApiClient.getStatusesService();
statusesService.update(message, null, null, null, null, null, null, null, mediaId, new Callback<Tweet>() {
#Override
public void success(Result<Tweet> result) {
dismissProgressDialog();
if(Validator.isNotNull(preferences.getImagePath()) && !preferences.getImagePath().isEmpty()) {
preferences.getImagePath().clear();
}
com.aimdek.healthwel.network.Request.getRequest().sendRequest(com.aimdek.healthwel.network.Request.SHARE_USER_HISTORY, TwitterIntegration.this, TwitterIntegration.this, RequestParameterBuilder.buildMapForShareUserHistory(userHistory.getId(), TwitterIntegration.this));
}
#Override
public void failure(TwitterException exception) {
if(Validator.isNotNull(preferences.getImagePath()) && !preferences.getImagePath().isEmpty()) {
preferences.getImagePath().clear();
}
dismissProgressDialog();
finish();
HWUtil.showToast(TwitterIntegration.this,exception.getMessage());
}
});
}
Related
I want to upload multiple image from gallery to server but getting only one image not multiple.
following is the code for it
FirstFragment.java
private void orderRequest() {
final OrderRequestModel model = basicInfiFragment.getData();
model.setSs(steelFragment.getProductInfo());
model.setAluminium(aluminiumFragment.getProductInfo());
SimpleMultiPartRequest orderRequest = new SimpleMultiPartRequest(Request.Method.POST,
Constance.baseURL + Constance.orderURL, new com.android.volley.Response.Listener<String>() {
#Override
public void onResponse(String response) {
DialogUtil.hideProgrss();
ProductModel mResponse = new Gson().fromJson(response, ProductModel.class);
if (mResponse.getStatus().equalsIgnoreCase(Constance.success)) {
Toast.makeText(getContext(), mResponse.getMessage(), Toast.LENGTH_SHORT).show();
Intent intent = new Intent(getContext(), MainActivity.class);
getContext().startActivity(intent);
getActivity().finish();
} else {
SnackUtil.mackText(mBinding.layoutRoot, mResponse.getMessage(), true);
}
L.e(response);
}
}, new com.android.volley.Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
L.e(error.toString());
DialogUtil.hideProgrss();
DialogUtil.someThingWentWrong(getContext());
}
});
Map<String, String> headerMap = new HashMap<>();
headerMap.put("token", SP.getString(SP.TOKEN));
for (ImageDetails imageDetails : model.getImageList()) {
orderRequest.addStringParam("json", new Gson().toJson(model));
orderRequest.addFile("siteImages",imageDetails.getPath());
orderRequest.addMultipartParam(imageDetails.getName(), getActivity().
getContentResolver().getType(imageDetails.getURI()), imageDetails.getPath());
orderRequest.setHeaders(headerMap);
}
DialogUtil.showProgress(getContext());
RequestQueue requestQueue = Volley.newRequestQueue(getContext());
requestQueue.add(orderRequest);
}
i tried a lot but it is uploading only one image please help me out of these getting stuck since last three days..
SecondFragment.java
public OrderRequestModel getData() {
OrderRequestModel model = new OrderRequestModel();
try {
model.setImageList(imageDetails);
} catch (Exception e) {
SnackUtil.mackText(mBinding.layoutRoot, getString(R.string.some_things_went_wrong), true);
L.e("date parse Error : " + e.getMessage());
}
return model;
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch (requestCode) {
case 122:
if (data != null) {
if (resultCode == Activity.RESULT_OK) {
Bitmap image = (Bitmap) data.getExtras().get("data");
String strData = String.valueOf(data.getData());
L.e("Camera : " + strData);
if (image != null) {
ImageDetails imgDetails = new ImageDetails();
imgDetails.setName(MyUtil.getFilename(Uri.parse(strData), getActivity()));
imgDetails.setBitmap(image);
imgDetails.setName("image" + new Random().nextInt(1000));
imageDetails.add(imgDetails);
}
}
adapterImages.notifyDataSetChanged();
}
break;
case 144:
if (data != null) {
if (resultCode == Activity.RESULT_OK) {
String strData = data.getDataString();
Uri[] resultFileChooser = null;
try {
if (data.getClipData() == null) {
L.e("data Clicp is Null");
}
resultFileChooser = new Uri[data.getClipData().getItemCount()];
for (int i = 0; i < data.getClipData().getItemCount(); i++) {
ImageDetails details = new ImageDetails();
details.setPath(getPath(data.getClipData().getItemAt(i).getUri()));
details.setURI(data.getClipData().getItemAt(i).getUri());
details.setName(MyUtil.getFilename(data.getClipData().getItemAt(i).getUri(), getActivity()));
imageDetails.add(details);
L.e("Uri : " + details.getPath());
}
} catch (NullPointerException e) {
if (strData != null) {
resultFileChooser = new Uri[]{Uri.parse(strData)};
ImageDetails imgDetails = new ImageDetails();
imgDetails.setName(MyUtil.getFilename(Uri.parse(strData), getActivity()));
imgDetails.setPath(getPath(Uri.parse(strData)));
imgDetails.setURI(Uri.parse(strData));
imageDetails.add(imgDetails);
L.e("Uri : " + imgDetails.getPath());
}
}
}
adapterImages.notifyDataSetChanged();
}
break;
}
}
this is the code which i am trying i paste my onActivity code and multipart code also.
you may want to enable multi-selection while selection and then syncing with the server.
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);
intent.setType("image/*");
startActivityForResult(intent, READ_REQUEST_CODE);
you will receive multiple Uri in your onActivity from there use to get file objects and then sync with the server.
I am making a edit profile page , in which i display profile picture of the user the user can edit the profile picture . before clicking submit the i want to save the final updated url of profile picture . The problem is that if i change the profile picture and and instantly click on submit the value of variable storing the url doen not change but if i wait for few seconds it changes is there a way to get the value updated instantly.
**My edit profile class**
public class DocEditProfileInfo extends DocBaseActivity {
private static final String TAG =
private String profilePicUrl;
public String profilepicUrlComplete;
ArrayList<String> mImagesString = new ArrayList<>();
private ProgressBar imageProgressBar;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ButterKnife.bind(this);
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN);
imageProgressBar = (ProgressBar) findViewById(R.id.progress);
setUpRestAdapter();
setSalutation();
setDocPersonalDetails();
ImageView iv = (ImageView) findViewById(R.id.camera_new);
iv.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
setDialogForImage();
}
});
docSubmitInfo.setOnClickListener(this);
}
private void setDialogForImage() {
final Dialog dialog = new Dialog(this);
dialog.setContentView(R.layout.dialog_select_from_source);
Button btnCamera = (Button) dialog.findViewById(R.id.btnCamera);
Button btnDocs = (Button) dialog.findViewById(R.id.btnDoc);
btnDocs.setVisibility(View.INVISIBLE);
Button btnGallery = (Button) dialog.findViewById(R.id.btnGallery);
dialog.show();
btnCamera.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(intent, 0);
dialog.cancel();
}
});
btnGallery.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent galleryIntent = new Intent(Intent.ACTION_PICK,
android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
// Start the Intent
startActivityForResult(galleryIntent, PICK_FROM_GALLERY);
dialog.cancel();
}
});
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
Uri mImageCaptureUri;
if (resultCode != RESULT_OK) {
return;
}
if (requestCode == 0 && resultCode == RESULT_OK) {
Bitmap bp = (Bitmap) data.getExtras().get("data");
// Uri selectedImageUri = data.getData();
// Glide.with(this).load(selectedImageUri).fitCenter().into(personImage);
personImage.setImageBitmap(getRoundedShape(bp));
// personImage.setImageBitmap(bp);
// CALL THIS METHOD TO GET THE URI FROM THE BITMAP
Uri tempUri = getImageUri(getApplicationContext(), bp);
// CALL THIS METHOD TO GET THE ACTUAL PATH
File filePath = new File(getRealPathFromURI(tempUri));
sendImagesToServerFromCamera(filePath.getPath());
} else if (requestCode == PICK_FROM_GALLERY && resultCode == RESULT_OK) {
/* Uri selectedImageUri = data.getData();
Log.e(TAG, "onActivityResult: URI " + selectedImageUri);
Glide.with(this).load(selectedImageUri).into(personImage);*/
Uri selectedImage = data.getData();
String[] filePathColumn = {MediaStore.Images.Media.DATA};
// Get the cursor
Cursor cursor = getContentResolver().query(selectedImage,
filePathColumn, null, null, null);
// Move to first row
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
String imgDecodableString = cursor.getString(columnIndex);
cursor.close();
// Set the Image in ImageView after decoding the String
personImage.setImageBitmap(getRoundedShape(BitmapFactory
.decodeFile(imgDecodableString)));
sendImagesToServerFromCamera(imgDecodableString);
}
}
public Bitmap getRoundedShape(Bitmap scaleBitmapImage) {
*******
}
private String getRealPathFromURI(Uri tempUri) {
********
}
public Uri getImageUri(Context inContext, Bitmap inImage) {
*********
}
private void sendImagesToServerFromCamera(String path) {
File imgPath = new File(path);
Log.e(TAG, "PATH " + path);
RequestBody requestFile =
RequestBody.create(MediaType.parse("image/jpg"), imgPath);
//For sending all types of images , presently only jpg allowed
// RequestBody fbody = RequestBody.create(MediaType.parse("image/*"), imgPath);
MultipartBody.Part body =
MultipartBody.Part.createFormData("file", imgPath.getName(), requestFile);
/* MultipartBody.Part body =
MultipartBody.Part.createFormData("file", imgPath.getName(), fbody);*/
Call<ProfilePicture> call = ProfilePicAdapter.sendProfilePic(body);
call.enqueue(new Callback<ProfilePicture>() {
#Override
public void onResponse(Call<ProfilePicture> call, Response<ProfilePicture> response) {
if (response.isSuccessful()) {
profilePicUrl = response.body().getUrl();
// profilepicUrlComplete = BASE_URL_FOR_IMAGE + profilePicUrl;
// String profilePicUrl = BASE_URL_FOR_IMAGE + profilePicUrl;
if (response.body().getUrl() != null) {
profilePicUrl = response.body().getUrl();
String profilePictureUrlComplete = BASE_URL_FOR_IMAGE + profilePicUrl;
setProfilePicURL(profilePictureUrlComplete);
}
} else {
Log.e(TAG, "UNSUCCESSFUL RESPONSE " + response.errorBody() + "*" + response.code());
}
}
#Override
public void onFailure(Call<ProfilePicture> call, Throwable t) {
Log.e(TAG, "onFailure: " + t.toString());
}
});
}
private void setProfilePicURL(String profilePictureUrlComplete) {
profilepicUrlComplete = profilePictureUrlComplete;
Log.e(TAG, "setProfilePicURL: " + profilePictureUrlComplete);
}
private void setDocPersonalDetails() {
*********
}
#Override
public void onClick(View v) {
if (isEditProfileValid()) {
Log.e(TAG, "onClick: PROFILE URL " + profilepicUrlComplete);
***docPersonalDetailsUpdate.setProfilePic(profilepicUrlComplete);***
Call<DoctorProfile> call = docPersonalDetailsUpdateAdapter.docEditPersonalDetails(docPersonalDetailsUpdate);
if (NetworkUtils.isNetworkConnected(this)) {
call.enqueue(new Callback<DoctorProfile>() {
#Override
public void onResponse(Call<DoctorProfile> call, Response<DoctorProfile> response) {
if (response.isSuccessful()) {
finish();
}
}
#Override
public void onFailure(Call<DoctorProfile> call, Throwable t) {
Log.e(TAG, "onFailure: ");
}
});
} else {
SnakBarUtils.networkConnected(this);
}
}
I am using the Fabric of the Twitter for sharing the video.I am not able to share the video on the twitter and yet now i am sharing the images only by the help of Fabric
Below is my lines of code for the fabric integration
public class MainActivity extends AppCompatActivity {
// Note: Your consumer key and secret should be obfuscated in your source code before shipping.
private static final String TWITTER_KEY = "xxxxxxx";
private static final String TWITTER_SECRET = "xxxxxxxxxxxxxxxxxxxxxxxxx";
private TwitterAuthClient authclient;
private TwitterLoginButton loginButton;
private String selectedImagePath;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
TwitterAuthConfig authConfig = new TwitterAuthConfig(TWITTER_KEY, TWITTER_SECRET);
Fabric.with(this, new Twitter(authConfig));
setContentView(R.layout.activity_main);
authclient = new TwitterAuthClient();
loginButton = (TwitterLoginButton) findViewById(R.id.twitter_login_button);
loginButton.setCallback(new Callback<TwitterSession>() {
#Override
public void success(Result<TwitterSession> result) {
// The TwitterSession is also available through:
// Twitter.getInstance().core.getSessionManager().getActiveSession()
TwitterSession session = result.data;
// TODO: Remove toast and use the TwitterSession's userID
// with your app's user model
String msg = "#" + session.getUserName() + " logged in! (#" + session.getUserId() + ")";
Toast.makeText(getApplicationContext(), msg, Toast.LENGTH_LONG).show();
}
#Override
public void failure(TwitterException exception) {
Log.d("TwitterKit", "Login with Twitter failure", exception);
}
});
Button share_btn = (Button)findViewById(R.id.share_btn);
share_btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(Intent.ACTION_PICK, MediaStore.Video.Media.EXTERNAL_CONTENT_URI);
intent.setType("video/*");
startActivityForResult(intent, 3);
}
});
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK) {
try {
if (requestCode == 3) {
Uri selectedImageUri = data.getData();
// OI FILE Manager
selectedImagePath = selectedImageUri.getPath();
// MEDIA GALLERY
selectedImagePath = getPath(selectedImageUri);
System.out.println("Here is the data ==>> " + selectedImagePath+" ");
TweetComposer.Builder builder = new TweetComposer.Builder(MainActivity.this)
.text("")
.image(Uri.parse(selectedImagePath));
builder.show();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
public String getPath(Uri uri) {
String[] projection = {MediaStore.Images.Media.DATA};
Cursor cursor = managedQuery(uri, projection, null, null, null);
if (cursor != null) {
// HERE YOU WILL GET A NULLPOINTER IF CURSOR IS NULL
// THIS CAN BE, IF YOU USED OI FILE MANAGER FOR PICKING THE MEDIA
int column_index = cursor
.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
return cursor.getString(column_index);
} else
return null;
}
}
I have got the solution for uploading the video using Twitter's Fabrics
Here is the below lines of code to upload the video on Twitter , using the Fabric
File myVideoFile = new File("HERE_IS_YOURS_SD_CARD_VIDEO_PATH");
Uri myVideoUri = Uri.fromFile(myVideoFile);
TweetComposer.Builder builder = new TweetComposer.Builder(MainActivity.this)
.text("YOUR_TEXT_MESSAGE") //Here is yours message which you want to send..If u does not require than remove this method
.image(myVideoUri );
builder.show();
I'm using MvvmCross on Android via Xamarin and i got a problem. I created a core service interface called IFileExplorerService.
This interface goal is to open a open file dialog and select a file whatever the device is (Windows or android).
On android i managed easly to do this without my interface via view by just using the OnActivityResult and Intents.
But i just cannot make it work from my view, as the interface implementation is a singleton registered in the setup, when i call it from my viewmodel there is absolutely no one to handle the OnActivityResult.
I tried to make my FileExplorer implmentation to inherit from Activity or MvxActivity, for this way my FileExplorer could override OnActivityResult, but this fails.
I tried to use StartActivity(typeof(FileExplorer)) but this obviously would fails anyway as it wouldn't be the singleton registered in MvvmCross that would be started.
Does anyone has any idea/comment/question/suggestion to help me on this?
Here is my code so far :
public class FileExplorerService : IFileExplorerServiceMock
{
string _addedFileName;
public static int REQUEST_FILE_CAPTURE = 2;
private bool _hasMediaBeenAdded;
private TaskCompletionSource<String> GetFileTask;
public Activity activity;
public FileExplorerService()
{
GetFileTask = new TaskCompletionSource<string>();
}
private void DispatchSelectFileIntent()
{
Intent Intent = new Intent();
Intent.SetType("*/*");
Intent.SetAction(Intent.ActionGetContent);
activity.StartActivityForResult(Intent.CreateChooser(Intent, "Select File"), REQUEST_FILE_CAPTURE);
}
public void OnActivityResult(int requestCode, [GeneratedEnum] Result resultCode, Intent data)
{
//
if (resultCode == Result.Ok)
{
if (data != null)
{
bool isFileCopied = CopySelectedFileToAddedFilesDirectory(data.Data);
if (isFileCopied)
{
//everything went well
ShowSuccesAlertDialog();
GetFileTask.SetResult(_addedFileName);
}
else
{
ShowFailureAlertDialog();
//oops something crashed
//Log
}
}
}
else
{
_addedFileName = String.Empty;
}
}
private void ShowFailureAlertDialog()
{
AlertDialog.Builder builder = new AlertDialog.Builder(activity);
AlertDialog alertDialog = builder.Create();
alertDialog.SetTitle("Oops... something went wrong");
alertDialog.SetIcon(Android.Resource.Drawable.IcDialogAlert);
alertDialog.SetMessage("Something went rong when adding a media");
alertDialog.SetButton("Ok", (s, ev) =>
{
});
alertDialog.Show();
}
private void ShowSuccesAlertDialog()
{
AlertDialog.Builder builder = new AlertDialog.Builder(activity);
AlertDialog alertDialog = builder.Create();
alertDialog.SetTitle("Media added with succes !");
alertDialog.SetIcon(Android.Resource.Drawable.IcDialogAlert);
alertDialog.SetMessage("Your media has been added with succes");
alertDialog.SetButton("Ok", (s, ev) =>
{
_hasMediaBeenAdded = true;
});
alertDialog.Show();
}
private void DeletePreviousAddedFile()
{
//todo delete file only if selected rex type is the same
if (_hasMediaBeenAdded)
{
MsFile.Delete(_addedFileName);
_addedFileName = string.Empty;
_hasMediaBeenAdded = false;
}
}
private static string GetRealPathFromURI(Context _context, Android.Net.Uri contentUri)
{
string[] projection = new string[] { MediaStore.MediaColumns.Data };
ContentResolver cr = _context.ContentResolver;
Android.Database.ICursor cursor = cr.Query(contentUri, projection, null, null, null);
if (cursor != null && cursor.Count > 0)
{
cursor.MoveToFirst();
int index = cursor.GetColumnIndex(Android.Provider.MediaStore.MediaColumns.Data);
return cursor.GetString(index);
}
return "";
}
private bool CopySelectedFileToAddedFilesDirectory(Android.Net.Uri data)
{
var dir = new Java.IO.File(Android.OS.Environment.ExternalStorageDirectory.AbsolutePath + "/Medias/AddedMedias/Files/");
if (!dir.Exists())
dir.Mkdirs();
string path = Android.OS.Environment.ExternalStorageDirectory.AbsolutePath + "/Medias/AddedMedias/Files/";
JavaFile file = new Java.IO.File(path);
string realPath = GetRealPathFromURI(activity.ApplicationContext, data);
string FileName = realPath.Split('/').Last();
_addedFileName = Path.Combine(dir + "/" + FileName);
if (!string.IsNullOrEmpty(realPath))
{
//todo manage errors
using (FileStream fs = new FileStream(realPath, FileMode.Open))
{
byte[] datas = new byte[fs.Length];
int numberBytesToRead = (int)fs.Length;
int numBytesRead = 0;
while (numberBytesToRead > 0)
{
int n = fs.Read(datas, numBytesRead, numberBytesToRead);
if (n == 0)
{
break;
}
numBytesRead += n;
numberBytesToRead -= n;
}
using (FileStream fs2 = System.IO.File.OpenWrite(Path.Combine(dir + "/" + FileName)))
{
fs2.Write(datas, 0, datas.Length);
}
}
return true;
}
return false;
}
public List<FileType> FileTypes
{
get
{
return new List<FileType>();
}
}
public async Task<string> Show(string fiel)
{
if (activity != null)
{
DeletePreviousAddedFile();
DispatchSelectFileIntent();
return GetFileTask.Task.Result;
}
else
{
return String.Empty;
}
}
And in my view :
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
SetContentView(Resource.Layout.RexView);
_addMediaController = new AddMediaController(this, (RexViewModel)base.ViewModel);
_flyoutMenuAnimator = new FlyoutMenuAnimator(this);
var t= Mvx.Resolve<IFileExplorerServiceMock>() as FileExplorerService;
t.activity = this;
}
protected override void OnActivityResult(int requestCode, Result resultCode, Intent data)
{
var t = Mvx.Resolve<IFileExplorerServiceMock>() as FileExplorerService;
t.OnActivityResult(requestCode, resultCode, data);
base.OnActivityResult(requestCode, resultCode, data);
}
With this everything work except that OnActivityResult is never called in my view
Okay i solved it ! Thanks to this link https://forums.xamarin.com/discussion/45691/pass-data-from-android-project-to-pcl
I had to rewrite start activity to give it a callback as an argument, the callback being my OnActivityResult in my file Explorer.
Here is my the code for anyone needing it :
in MyView:
private Action<int, Result, Intent> _resultCallback;
public void StartActivity(Intent intent,int resultCode, Action<int, Result, Intent> resultCallback)
{
_resultCallback = resultCallback;
StartActivityForResult(intent, resultCode);
}
protected override void OnActivityResult(int requestCode, Result resultCode, Intent data)
{
base.OnActivityResult(requestCode, resultCode, data);
if (_resultCallback != null)
{
_resultCallback(requestCode, resultCode, data);
_resultCallback = null;
}
}
and in my file Explorer :
string _addedFileName;
public static int REQUEST_FILE_CAPTURE = 2;
private bool _hasMediaBeenAdded;
private TaskCompletionSource<String> GetFileTask;
public RexView activity;
public FileExplorerService()
{
}
private void DispatchSelectFileIntent()
{
Intent intent = new Intent();
intent.SetType("*/*");
intent.SetAction(Intent.ActionGetContent);
GetFileTask = new TaskCompletionSource<string>();
activity.StartActivity(Intent.CreateChooser(intent, "Select File"), REQUEST_FILE_CAPTURE, OnActivityResult);
// activity.StartActivityForResult(Intent.CreateChooser(intent, "Select File"), REQUEST_FILE_CAPTURE);
}
public void OnActivityResult(int requestCode, [GeneratedEnum] Result resultCode, Intent data)
{
//
if (resultCode == Result.Ok)
{
if (data != null)
{
bool isFileCopied = CopySelectedFileToAddedFilesDirectory(data.Data);
if (isFileCopied)
{
//everything went well
ShowSuccesAlertDialog();
GetFileTask.SetResult(_addedFileName);
}
else
{
ShowFailureAlertDialog();
//oops something crashed
//Log
}
}
}
else
{
_addedFileName = String.Empty;
}
}
private void ShowFailureAlertDialog()
{
AlertDialog.Builder builder = new AlertDialog.Builder(activity);
AlertDialog alertDialog = builder.Create();
alertDialog.SetTitle("Oops... something went wrong");
alertDialog.SetIcon(Android.Resource.Drawable.IcDialogAlert);
alertDialog.SetMessage("Something went rong when adding a media");
alertDialog.SetButton("Ok", (s, ev) =>
{
});
alertDialog.Show();
}
private void ShowSuccesAlertDialog()
{
AlertDialog.Builder builder = new AlertDialog.Builder(activity);
AlertDialog alertDialog = builder.Create();
alertDialog.SetTitle("Media added with succes !");
alertDialog.SetIcon(Android.Resource.Drawable.IcDialogAlert);
alertDialog.SetMessage("Your media has been added with succes");
alertDialog.SetButton("Ok", (s, ev) =>
{
_hasMediaBeenAdded = true;
});
alertDialog.Show();
}
private void DeletePreviousAddedFile()
{
//todo delete file only if selected rex type is the same
if (_hasMediaBeenAdded)
{
MsFile.Delete(_addedFileName);
_addedFileName = string.Empty;
_hasMediaBeenAdded = false;
}
}
private static string GetRealPathFromURI(Context _context, Android.Net.Uri contentUri)
{
string[] projection = new string[] { MediaStore.MediaColumns.Data };
ContentResolver cr = _context.ContentResolver;
Android.Database.ICursor cursor = cr.Query(contentUri, projection, null, null, null);
if (cursor != null && cursor.Count > 0)
{
cursor.MoveToFirst();
int index = cursor.GetColumnIndex(Android.Provider.MediaStore.MediaColumns.Data);
return cursor.GetString(index);
}
return "";
}
private bool CopySelectedFileToAddedFilesDirectory(Android.Net.Uri data)
{
var dir = new Java.IO.File(Android.OS.Environment.ExternalStorageDirectory.AbsolutePath + "/Medias/AddedMedias/Files/");
if (!dir.Exists())
dir.Mkdirs();
string path = Android.OS.Environment.ExternalStorageDirectory.AbsolutePath + "/Medias/AddedMedias/Files/";
JavaFile file = new Java.IO.File(path);
string realPath = GetRealPathFromURI(activity.ApplicationContext, data);
string FileName = realPath.Split('/').Last();
_addedFileName = Path.Combine(dir + "/" + FileName);
if (!string.IsNullOrEmpty(realPath))
{
//todo manage errors
using (FileStream fs = new FileStream(realPath, FileMode.Open))
{
byte[] datas = new byte[fs.Length];
int numberBytesToRead = (int)fs.Length;
int numBytesRead = 0;
while (numberBytesToRead > 0)
{
int n = fs.Read(datas, numBytesRead, numberBytesToRead);
if (n == 0)
{
break;
}
numBytesRead += n;
numberBytesToRead -= n;
}
using (FileStream fs2 = System.IO.File.OpenWrite(Path.Combine(dir + "/" + FileName)))
{
fs2.Write(datas, 0, datas.Length);
}
}
return true;
}
return false;
}
public List<FileType> FileTypes
{
get
{
return new List<FileType>();
}
}
public async Task<string> Show(string fiel)
{
if (activity != null)
{
DeletePreviousAddedFile();
DispatchSelectFileIntent();
return await GetFileTask.Task;
}
else
{
return String.Empty;
}
}
}
And in my view model
private async void BrowseMedias()
{
var fileExplorerService = Mvx.Resolve<IFileExplorerServiceMock>();
fileExplorerService.FileTypes.Add(FileType.Picture);
string fileSavedPath = await fileExplorerService.Show(DatabaseContentPath);
/* file managment*/
}
I have some places in a listView. These are picked from a Google Map, for which I would like to take a picture. One for each. These photos should be available online, so I have searched for some proper solutions. I've choosed imgur's API.
Is it possible to link pictures with places? I would like to make mapping between uploaded pictures and listView items.
Photo picker and uploader class:
public class OAuthTestActivity extends Activity {
public static final int REQUEST_CODE_PICK_IMAGE = 1001;
private static final String AUTHORIZATION_URL = "https://api.imgur.com/oauth2/authorize";
private static final String CLIENT_ID = "CLIENT_ID";
private LinearLayout rootView;
private String accessToken;
private String refreshToken;
private String picturePath = "";
private Button send;
private String uploadedImageUrl = "";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
rootView = new LinearLayout(this);
rootView.setOrientation(LinearLayout.VERTICAL);
TextView tv = new TextView(this);
LinearLayout.LayoutParams llp = new LinearLayout.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
tv.setLayoutParams(llp);
rootView.addView(tv);
setContentView(rootView);
String action = getIntent().getAction();
if (action == null || !action.equals(Intent.ACTION_VIEW)) { // We need access token to use Imgur's api
tv.setText("Start OAuth Authorization");
Uri uri = Uri.parse(AUTHORIZATION_URL).buildUpon()
.appendQueryParameter("client_id", CLIENT_ID)
.appendQueryParameter("response_type", "token")
.appendQueryParameter("state", "init")
.build();
Intent intent = new Intent();
intent.setData(uri);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
finish();
} else { // Now we have the token, can do the upload
tv.setText("Got Access Token");
Uri uri = getIntent().getData();
Log.d("Got imgur's access token", uri.toString());
String uriString = uri.toString();
String paramsString = "http://callback?" + uriString.substring(uriString.indexOf("#") + 1);
Log.d("tag", paramsString);
List<NameValuePair> params = URLEncodedUtils.parse(URI.create(paramsString), "utf-8");
Log.d("tag", Arrays.toString(params.toArray(new NameValuePair[0])));
for (NameValuePair pair : params) {
if (pair.getName().equals("access_token")) {
accessToken = pair.getValue();
} else if (pair.getName().equals("refresh_token")) {
refreshToken = pair.getValue();
}
}
Log.d("tag", "access_token = " + accessToken);
Log.d("tag", "refresh_token = " + refreshToken);
Button chooseImage = new Button(this);
rootView.addView(chooseImage);
chooseImage.setText("Choose an image");
chooseImage.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(intent, REQUEST_CODE_PICK_IMAGE);
}
});
send = new Button(this);
rootView.addView(send);
send.setText("send to imgur");
send.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (picturePath != null && picturePath.length() > 0 &&
accessToken != null && accessToken.length() > 0) {
(new UploadToImgurTask()).execute(picturePath);
}
}
});
}
}
#Override
protected void onResume() {
super.onResume();
if (send == null) return;
if (picturePath == null || picturePath.length() == 0) {
send.setVisibility(View.GONE);
} else {
send.setVisibility(View.VISIBLE);
}
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
Log.d("tag", "request code : " + requestCode + ", result code : " + resultCode);
if (data == null) {
Log.d("tag" , "data is null");
}
if (resultCode == Activity.RESULT_OK && requestCode == REQUEST_CODE_PICK_IMAGE && null != data) {
Uri selectedImage = data.getData();
String[] filePathColumn = { MediaStore.Images.Media.DATA };
Cursor cursor = getContentResolver().query(selectedImage,
filePathColumn, null, null, null);
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
picturePath = cursor.getString(columnIndex);
Log.d("tag", "image path : " + picturePath);
cursor.close();
}
super.onActivityResult(requestCode, resultCode, data);
}
// Here is the upload task
class UploadToImgurTask extends AsyncTask<String, Void, Boolean> {
#Override
protected Boolean doInBackground(String... params) {
final String upload_to = "https://api.imgur.com/3/upload";
HttpClient httpClient = new DefaultHttpClient();
HttpContext localContext = new BasicHttpContext();
HttpPost httpPost = new HttpPost(upload_to);
try {
HttpEntity entity = MultipartEntityBuilder.create()
.addPart("image", new FileBody(new File(params[0])))
.build();
httpPost.setHeader("Authorization", "Bearer " + accessToken);
httpPost.setEntity(entity);
final HttpResponse response = httpClient.execute(httpPost,
localContext);
final String response_string = EntityUtils.toString(response
.getEntity());
final JSONObject json = new JSONObject(response_string);
Log.d("tag", json.toString());
JSONObject data = json.optJSONObject("data");
uploadedImageUrl = data.optString("link");
Log.d("tag", "uploaded image url : " + uploadedImageUrl);
return true;
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
#Override
protected void onPostExecute(Boolean aBoolean) {
super.onPostExecute(aBoolean);
if (aBoolean.booleanValue()) { // after sucessful uploading, show the image in web browser
Button openBrowser = new Button(OAuthTestActivity.this);
rootView.addView(openBrowser);
openBrowser.setText("Open Browser");
openBrowser.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent();
intent.setData(Uri.parse(uploadedImageUrl));
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
}
});
}
}
}
}