Hallo, I writing an app and I want to integrate a sketch-app to draw something and pass the file or path back to my app. At the moment the app can store videos,pictures, sensor data,... and I like to add the ability to store sketches. I found this Code
final Intent intent = new Intent(Intent.ACTION_MAIN, null);
intent.addCategory(Intent.CATEGORY_LAUNCHER);
final ComponentName cn = new ComponentName("com.android.settings", "com.android.settings.fuelgauge.PowerUsageSummary");
intent.setComponent(cn);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity( intent);
But i dont know how to start sketchbook(app from market). And I need also the path to the saved picture.Or is there an other way? Or Open Source ?
greetings...
So sketchbook is not your application?
To start another program, you need to know the intent filters it uses, or the package name. The developer of sketchbook will be able to supply you with this information (if they wish to share it).
Now when it comes to getting data FROM another app, the only way for that app to return anything to you is if the developer made it that way. It is up to the developer to decide what an Activity returns (if anything). So if you are looking to integrate with a specific application, it would be best for you to contact that developer and discuss how the two apps will interface with each other. On the other hand, if you implemented your own sketch app, you could make it integrate however you'd like.
You'd need to detect that the intent can be handled by the system.
public static boolean canHandleIntent(final Context context, final Intent intent) {
if (intent != null) {
final PackageManager pm = context.getPackageManager();
if (pm != null) {
if (pm.queryIntentActivities(intent, 0).size() > 0) {
return true;
}
}
}
return false;
}
If that returns false you should prompt the user to download the app from the market.
Call,
//Market.getViewPackageOnMarket("org.otherapp.sketchapp");
public class Market {
public static final String Application_BaseMarketUri = "market://details?id=";
public static final Intent getViewPackageOnMarket(final String package_name) {
final Intent result = new Intent(Intent.ACTION_VIEW);
result.setData(Uri.parse(Application_BaseMarketUri + package_name));
return result;
}
}
You'll also need to use startActivityForResult, in your launching activity you need to add these things....
public class MyKillerAppActivity extends Activity {
// Declare constant for the activity result.
public static final int ACTIVITYRESULT_GETSKETCH = 1;
// Call the activity ....
public void someMethod() {
startActivityForResult(intent, ACTIVITYRESULT_GETSKETCH);
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if(resultCode == RESULT_OK) {
if(requestCode == ACTIVITYRESULT_GETSKETCH) {
handleGetSketchResult(data);
} /* Handle other results if you need to. */
}
}
}
That's kinda a mouthful but there's more! You'll need to interpret the data that comes back from the app. I don't know the format is for the sketch app you're looking into but here's an example on how to get data from the Gallery. The Gallery app returns you a content provider location to load the image that the user picked. This code locates the file path from the content provider and then opens the file and loads it into a Bitmap object for use.
public static Bitmap onActivityResult_getImage(Context context, Intent data) {
Bitmap result = null;
Uri dataUri = data.getData();
final String filePath = findPictureFilePath(context, dataUri);
if(filePath != null) {
result = BitmapFactory.decodeFile(filePath);
}
return result;
}
private static String findPictureFilePath(Context context, Uri dataUri) {
String filePath = null;
final String[] projection = { MediaStore.Images.Media.DATA };
Cursor cursor = null;
try {
cursor = context.getContentResolver().query(dataUri, projection, null, null, null);
int data_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
if(cursor.moveToFirst()) {
filePath = cursor.getString(data_index);
}
} finally {
if(cursor != null) {
cursor.close();
}
}
return filePath;
}
Related
when I open the gallery and go to dropbox or one drive I get a message unable to get path but when I go to google photos or local, I get the right image to load in a grid.
DependencyService.Get<IMediaService>().OpenGallery();
MessagingCenter.Unsubscribe<App, List<string>>((App)Xamarin.Forms.Application.Current, "ImagesSelectedAndroid");
MessagingCenter.Subscribe<App, List<string>>((App)Xamarin.Forms.Application.Current, "ImagesSelectedAndroid", (s, images) =>
{
if (images.Count > 0)
{
Console.WriteLine($"Processed {images.Count} images");
UploadToBlob(images);
GetGallery();
}
public void OpenGallery()
{
try
{
var imageIntent = new Intent(Intent.ActionPick);
imageIntent.SetType("image/*");
imageIntent.PutExtra(Intent.ExtraAllowMultiple, true);
imageIntent.SetAction(Intent.ActionGetContent);
((Activity)CrossCurrentActivity.Current.Activity).StartActivityForResult(Intent.CreateChooser(imageIntent, "Select photo"), Opengallerycode);
Toast.MakeText(CrossCurrentActivity.Current.Activity, "Tap and hold to select multiple photos.", ToastLength.Short)?.Show();
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
Toast.MakeText(CrossCurrentActivity.Current.Activity, "Error. Can not continue, try again.", ToastLength.Long)?.Show();
}
}
You could get the image into stream from dropbox or one drive and load in a grid.
Create the interface: IPhotoPickerService.cs
public interface IPhotoPickerService
{
Task<Stream> GetImageStreamAsync();
}
Android implementation:
MainActivity.cs
public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
{
internal static MainActivity Instance { get; private set; }
... ...
// Field, property, and method for Picture Picker
public static readonly int PickImageId = 1000;
public TaskCompletionSource<Stream> PickImageTaskCompletionSource { set; get; }
protected override void OnActivityResult(int requestCode, Result resultCode, Intent intent)
{
base.OnActivityResult(requestCode, resultCode, intent);
if (requestCode == PickImageId)
{
if ((resultCode == Result.Ok) && (intent != null))
{
Android.Net.Uri uri = intent.Data;
Stream stream = ContentResolver.OpenInputStream(uri);
// Set the Stream as the completion of the Task
PickImageTaskCompletionSource.SetResult(stream);
}
else
{
PickImageTaskCompletionSource.SetResult(null);
}
}
}
}
PhotoPickerService.cs
public class PhotoPickerService : IPhotoPickerService
{
public Task<Stream> GetImageStreamAsync()
{
// Define the Intent for getting images
Intent intent = new Intent();
intent.SetType("image/*");
intent.SetAction(Intent.ActionGetContent);
// Start the picture-picker activity (resumes in MainActivity.cs)
MainActivity.Instance.StartActivityForResult(
Intent.CreateChooser(intent, "Select Photo"),
MainActivity.PickImageId);
// Save the TaskCompletionSource object as a MainActivity property
MainActivity.Instance.PickImageTaskCompletionSource = new TaskCompletionSource<Stream>();
// Return Task object
return MainActivity.Instance.PickImageTaskCompletionSource.Task;
}
}
For more information about IOS, UWP implementation of photo picker, you could check the MS article. https://learn.microsoft.com/en-us/xamarin/xamarin-forms/app-fundamentals/dependency-service/photo-picker
And download the source file from link. https://learn.microsoft.com/zh-cn/samples/xamarin/xamarin-forms-samples/dependencyservice/
I am working on a Chatting application.I has successfully send text as a message to receiver, now i want to send image as a message either by capturing or selecting from the gallery.
I had gone through some of approaches like ACTION_SEND of Intent class. But find hard to implement it. I Had made separate class for those things which has to be send or receive.
public class ChatMessage {
private String messagetext;
private String messageuser;
private long messagetime;
ImageView iv;
public ChatMessage(String messagetext, String messageuser) {
this.messagetext = messagetext;
this.messageuser = messageuser;
messagetime= new Date().getTime();
}
public ChatMessage() {
}
public String getMessagetext() {
return messagetext;
}
public void setMessagetext(String messagetext) {
this.messagetext = messagetext;
}
public String getMessageuser() {
return messageuser;
}
public void setMessageuser(String messageuser) {
this.messageuser = messageuser;
}
public long getMessagetime() {
return messagetime;
}
public void setMessagetime(long messagetime) {
this.messagetime = messagetime;
}
}
and i populate these via following method:
private void displayChatMessage(){
final ListView listofmessage= (ListView)findViewById(R.id.list_of_message);
adapter=new FirebaseListAdapter<ChatMessage>(this,ChatMessage.class,R.layout.list_item,FirebaseDatabase.getInstance().getReference()) {
#Override
protected void populateView(View v, ChatMessage model, int position) {
TextView messagetext,messaggeuser,messagetime;
messagetext=(TextView)v.findViewById(R.id.message_text);
messaggeuser=(TextView)v.findViewById(R.id.message_user);
messagetime=(TextView)v.findViewById(R.id.message_time);
messagetext.setText(model.getMessagetext());
messaggeuser.setText(model.getMessageuser());
messagetime.setText(DateFormat.format("dd-mm-yyyy (HH:mm:ss)",model.getMessagetime()));
}
};
listofmessage.setAdapter(adapter);
}
so, please suggest some approaches. Thanks.
First of all, you need to create a custom dialog or pop-up window to make the user choose whether he wants to capture an image with the camera or he want to select one from the gallery, Then you need to dispatch the right intent depend on what he will choose so if he chooses to capture and image from the gallery this will be your intent
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent, "Select Picture"), yourRequestCode);
Your request code is simply an int you can distinguish with later when a result comes that it was the response for this intent action.
if the user chooses to snap a picture with the camera this is how your intent will be like
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, selectedImageUri);
startActivityForResult(intent, antherRequestCode);
then after he successfully grab a picture from the gallery or snap one with the camera onActivityResult method will be invoked with the returned image, and there where you should handle what you are going to do with that image so first you ovride the method
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == RESULT_OK ){
switch (requestCode) {
case GALLERY_INTENT_REQUEST_CODE:
Uri imageUri = data.getData();
Log.e("ImageUri", imageUri != null ? imageUri.toString() : "Empty Uri");
break;
case TAKE_IMAGE_INTENT_REQUEST_CODE:
Bundle extras = data.getExtras();
Bitmap imageBitmap = (Bitmap) extras.get("data");
Log.e("ImageUri", extras != null ? imageBitmap.toString() : "no Bitmap found");
break;
}
}
}
So as you can see from the code above the gallery intent returns the image Uri and the camera intent return a bitmap and now that you have the image you can encoded to base64 or turn it to a byte array or adding it to a file and send it to the desired reciever.
I'm trying to send an image path from one activity to another. I'm catching the intent in onResume, but the string path is always null. I don't know what I'm doing wrong. Hopefully you guys can help me with this problem.
Here's my activity where I grab the image path and send an intent.
private Intent testImage = new Intent(this, MyActivity.class);
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.card_create_layout);
testImage = new Intent(this, MyActivity.class);
}
private void grabImage()
{
Intent imageGetter = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(imageGetter, RESULT_LOAD_IMAGE);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
super.onActivityResult(requestCode, resultCode, data);
if(requestCode == RESULT_LOAD_IMAGE && resultCode == RESULT_OK && null != data)
{
Uri selectedImage = data.getData();
String[] filePathColumn = {MediaStore.Images.Media.DATA};//Array size of 1, and we put in a string
Cursor cursor = getContentResolver().query(selectedImage, filePathColumn, null, null, null);
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
user_image_path = cursor.getString(columnIndex);//here we have our image path.
cursor.close();
ImageView imageView = (ImageView) findViewById(R.id.imageView);
imageView.setImageBitmap(BitmapFactory.decodeFile(user_image_path));
}
testImage.putExtra("the_image", user_image_path);
}
#Override
public void onClick(View v)
{
switch (v.getId())
{
case R.id.theCreateButton:
grabImage();
break;
case R.id.theDesButton:
startActivity(sendInformation);
}
}
#Override
public void onBackPressed()
{
super.onBackPressed();
MyActivity.checkCard();
setResult(Activity.RESULT_OK, getIntent());
finish();
}
Now in my other activity, when I grab the image and press back
#Override
public void onResume()
{
super.onResume();
String ImagePath = getIntent().getStringExtra("the_image");
if(ImagePath == null)
{
Toast.makeText(this,"hello everyone",Toast.LENGTH_LONG).show();
}
}
It keeps on showing the toast message "hello everyone", which means ImagePath is continuously null. How do I fix this?
Pass mechanism between activities is available in three ways :
via DI(Dependency Injection)
via Bundle mechanism
via Singletone class which play a role a bridge or data holder between activities.
To avoid duplicating answer - please search any way(i recommend easiest - via Bundle) in stackoverflow.
Quick guide :
You put your string into bundle via intent.putExtra(String name, String value) in Activity A
Start this intent with startActivity(intent);
In B activity read value view getIntent().getStringExtra(String name) in OnCreate method.
name value is need the same in activity A and B. This is a key.
I don't see a
startActivity(testImage);
If you aren't using that intent to start the activity, then there is no extra called 'the_image' and the getStringExtra function will effectively return a null.
#Override
public void onBackPressed() {
Intent intent = new Intent();
intent.putExtra("the_image", user_image_path);
setResult(RESULT_OK, intent);
super.onBackPressed();
}
The above is how to correctly do it, if you have started an activity for result.
This is the first time I post something here, so I apologize in advance for any mistake what-so-ever.
This is the situation:
I'm currently developing my first android app, sort of like a tracker:
1. log in
2. select weather, temperature etc
3. press the start button that activates a background GPS service and shows you a list of other attendees
4. click on an attendee and it shows you a timeline where you can add pictures etc.
Here is where the fun starts. When I open the camera it works most of the time, but once in a while the activity that opens the camera gets destroyed and when reopening (to further progress) it opens a second camera.
When I take a picture like that it completely ignores the first picture, restarts the gps-service, messes up my timeline and shows the login dialog when I go back to the the main activity (which is programmed to only show up when starting the app).
I have read an similar topic and it might be the solution, but I can't get it to work.
The code for the camera activity:
public class AddPhotoActivity extends Activity {
private SharedPreferences savedValues;
private String mCurrentPhotoPath;
private String imageName;
private int id;
private String startRideDateTime;
private SimpleDateFormat dateInSQL = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
private Date date;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_add_photo);
savedValues = this.getSharedPreferences("SavedValues",
Context.MODE_PRIVATE);
id = savedValues.getInt("RideId", 0);
startRideDateTime = savedValues.getString("StartRideDateTime", "");
try {
date = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss").parse(startRideDateTime);
} catch (ParseException e) {
e.printStackTrace();
}
SimpleDateFormat dateInDir
= new SimpleDateFormat("yyyyMMdd_HHmmss");
startRideDateTime = dateInDir.format(date);
if (savedInstanceState == null) {
dispatchTakePictureIntent();
}
}
#Override
protected void onResume() {
super.onResume();
savedValues = this.getSharedPreferences("SavedValues",
Context.MODE_PRIVATE);
}
private void dispatchTakePictureIntent() {
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
File photoFile = null;
try {
photoFile = createImageFile();
} catch (IOException ex) {
ex.printStackTrace();
}
if (photoFile != null) {
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT,
Uri.fromFile(photoFile));
startActivityForResult(takePictureIntent, 1);
}
}
}
private File createImageFile() throws IOException {
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String imageFileName = "IMG_" + timeStamp;
File sdCard = Environment.getExternalStorageDirectory();
File storageDir = new File(sdCard.getAbsolutePath() + „/app/„ + id + "/" + startRideDateTime + "/photos");
storageDir.mkdirs();
File image = File.createTempFile(imageFileName, ".jpg", storageDir);
mCurrentPhotoPath = "file:" + image.getAbsolutePath();
imageName = image.getName();
return image;
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == RESULT_OK) {
if (mCurrentPhotoPath != null) {
addPhotoToDb();
mCurrentPhotoPath = null;
}
} else if (resultCode == RESULT_CANCELED) {
finish();
}
}
private void addPhotoToDb() {
TimeLineDataSource timeLineDataSource = new TimeLineDataSource(this);
timeLineDataSource.open();
date = new Date();
String dateString = dateInSQL.format(date);
timeLineDataSource.createTimeLineItem(3, imageName, dateString);
timeLineDataSource.close();
finish();
}
public void onBackPressed() {
finish();
}
}
If anybody knows a solution to this I would be eternally grateful!
Update:
although I had better code after the previous suggestion it still didn't solve the problem. It seems that devices with less memory can get terminated at DVM-level, causing them to quit without onDestroy(). My issue is more or less resolved, but includes a lot of patchwork that I feel can be done in other, more efficient ways.
The code below is what I usually use for taking a photo/picking a photo. I normally include the ability to pick a previous photo or take a new photo, and I don't run into this issue.
Intent takePicture = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(takePicture, 0);
//zero can be replced with any action code to pick photo from gallery
Intent pickPhoto = new Intent(Intent.ACTION_PICK,
android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(pickPhoto , 1);
//one can be replced with any action code
protected void onActivityResult(int requestCode, int resultCode, Intent imageReturnedIntent) {
super.onActivityResult(requestCode, resultCode, imageReturnedIntent);
switch(requestCode) {
case 0:
if(resultCode == RESULT_OK){
Uri selectedImage = imageReturnedIntent.getData();
imageview.setImageURI(selectedImage);
}
break;
case 1:
if(resultCode == RESULT_OK){
Uri selectedImage = imageReturnedIntent.getData();
imageview.setImageURI(selectedImage);
}
break;
}
}
Also, I agree with the solution from the other post, this in particular:
In the case of a destroyed activity, when the activity result needs to
be processed, Android will recreate the Activity, passing a
savedInstanceState to onCreate. So, the remedy is to check the value
of savedInstanceState in your GetImageActivity.onCreate. If it is not
null then don't make any calls to startActivity because your Activity
is being recreated to call onActivityResult.
Optionally, if you need to preserve any state then override
onSaveInstanceState(Bundle outState) and put data you need into
outState.
I'm having trouble querying for supported languages using the SpeechRecognizer.ACTION_GET_SUPPORTED_LANGUAGES.
private void queryLanguages() {
Intent i = new Intent(RecognizerIntent.ACTION_GET_LANGUAGE_DETAILS);
sendOrderedBroadcast(i, null);
}
Now, I know it says the BroadcastReceiver is specified in RecognizerIntent.DETAILS_META_DATA, but I'm not sure as to how I can access that.
So basically what I'm asking is how do I create an Intent to retrieve the available languages data?
This is how it is done:
Intent intent = new Intent(RecognizerIntent.ACTION_GET_LANGUAGE_DETAILS);
context.sendOrderedBroadcast(intent, null, new HintReceiver(),
null, Activity.RESULT_OK, null, null);
private static class HintReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if (DBG)
Log.d(TAG, "onReceive(" + intent.toUri(0) + ")");
if (getResultCode() != Activity.RESULT_OK) {
return;
}
// the list of supported languages.
ArrayList<CharSequence> hints = getResultExtras(true)
.getCharSequenceArrayList(
RecognizerIntent.EXTRA_SUPPORTED_LANGUAGES);
}
}
Note :
Whether these are actually provided is up to the particular implementation