I have the following sequence of pages:
-MainActivity
-Intent(Select a picture)
-DadosActivity
In MainActivity I have a button to open an intent for the user to select a photo, with the following code:
Intent i = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
if (i.resolveActivity(MainActivity.this.getPackageManager()) != null) {
startActivityForResult(i, SELECAO_GALERIA);
}
In this intent, the user will select a photo and after this is sent that selected item to another page, through this code:
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == MainActivity.this.RESULT_OK) {
Bitmap image = null;
try {
switch (requestCode) {
case SELECAO_CAMERA:
image = (Bitmap) data.getExtras().get("data");
break;
case SELECAO_GALERIA:
Uri localImagemSelecionada = data.getData();
image = MediaStore.Images.Media.getBitmap(MainActivity.this.getContentResolver(), localImagemSelecionada);
break;
}
if (image != null) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
image.compress(Bitmap.CompressFormat.JPEG, 70, baos);
byte[] dadosImagem = baos.toByteArray();
Intent i = new Intent(MainActivity.this, DadosPostagemActivity.class);
i.putExtra("fotoEscolhida", dadosImagem);
startActivity(i);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
In the last activity, DadosActivity, the user can make some changes in the image, but my problem is when pressing the button on the back of the device and / or the toolbar, with the following code:
toolbar = (Toolbar) findViewById(R.id.tb_dados);
toolbar.setTitle("Adicione uma descrição");
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
According to what I did on AndroidManifest
<activity
android:name=".activity.DadosPostagemActivity"
android:parentActivityName=".activity.MainActivity" />
Activity is returning to MainActivity, but I wanted to press it to return to the intent and to choose the image again.
Does anyone have any suggestions on how to do this, so that instead of returning to MainActivity, back to the intent so that he can choose the image again?
Use the Codes Below..
In Manifest.xml file change code of AddPhoto Activity and AddDescription Activity like this-
This is for Addphoto Activity
<activity android:name=".AddPhoto"
android:label="Add Photo"
android:parentActivityName=".MainActivity">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".MainActivity" />
</activity>
This is for AddDescription Activity
<activity android:name=".AddDescription"
android:label="Add Description"
android:parentActivityName=".AddPhoto">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".AddPhoto" />
</activity>
Now your problems are solved. In the code we declared that Addphoto activity is a child of Main Activity and AddDescription Activity is a child of Addphoto Acitivity.
Change the AddPhoto and AddDescription with your own activity name.
Best of Luck.
Thanks for everyone, I I found the solution was to just overwrite the method onBackPressed
Related
I just started using Android Studio to develop an experimental application. My current problem in trying to get one of my navigation bar tabs set to a camera tab so that when pressed, the camera opens, user takes a picture, then the program does something with that picture. However, when I tried to set the tab as a camera, the program immediately crashes after clicking on the tab. I have this portion of the code currently set as my Main for that specific tab.
case R.id.navigation.dashboard:
Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");
startActivity(intent);
return true;
Should I use a button as an alternative?
EDIT: changed title and some details to the question for more clarification
EDIT2: Got the problem fixed, thanks! The problem for me was actually not checking for app permissions manually via the app info even though I had these permission scripts on the XML file already.
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
So I forgot to add a permission popup on my program.
Couple of thing are wrong with this:
Why use tabs for camera if you are just going to use an intent for the camera picture.
The intent should look something like this:
Note: imageUri should be set here to be used later
void takePhoto(View view) {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
File photo = new File(Environment.getExternalStorageDirectory(), "image.jpg");
intent.putExtra(MediaStore.EXTRA_OUTPUT,
Uri.fromFile(photo));
imageUri = Uri.fromFile(photo);
startActivityForResult(intent, TAKE_PICTURE);
}
Since starting an activity for result you need to declare a variable TAKE_PICTURE:
private static final int TAKE_PICTURE = 123
Maybe you want to use tab for showing the picture, and that can look like this:
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch (requestCode) {
case TAKE_PICTURE:
if (resultCode == Activity.RESULT_OK) {
Uri selectedImage = imageUri;
getContentResolver().notifyChange(selectedImage, null);
Bitmap bitmap;
try {
bitmap = android.provider.MediaStore.Images.Media
.getBitmap(getContentResolver(), selectedImage);
// show image here in an imageView
} catch (Exception e) {
Log.e("Camera", e.toString());
}
}
}
}
If you don't want to open new Activity you can use CameraX library.
Here you have nice sample how to use it.
I need to share image and add "Save image" item in android share menu, I saw something like this in 9gag app, they have "Save" item in share menu, and share menu seems to be a bottom sheet. But how it can be achieved?
What I've done:
I added empty activity with intent filter in manifest which launches service and this service downloads image
<activity
android:name=".model.services.ShareActivity"
android:icon="#drawable/download_icon"
android:label="Save">
<intent-filter
android:label="Save"
android:icon="#drawable/download_icon">
<action android:name="android.intent.action.SEND" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="image/*"/>
</intent-filter>
</activity>
and now I have this icon in share menu and it works, but this icon also appear in share menu of other apps, I need to show it only in my app, how I can make it private or something?
Ok, I found a solution. First - we need activity which will handle image saving intent, this activity can launch service or something. I make it like this:
public class ShareActivity extends Activity {
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Bundle extras = getIntent().getExtras();
String url = extras.getString("url");
String name = extras.getString("name");
String description = extras.getString("description");
SaveImageService.downloadFile(url, name, description);
finish();
}
}
Where SaveImageService has static method which handle image saving to SD card
Second, we need to add some text in manifest:
<activity
android:name=".model.services.ShareActivity"
android:icon="#drawable/download_icon"
android:label="Save">
<intent-filter
android:label="Save"
android:icon="#drawable/download_icon">
<action android:name="com.my_app.random_text.SAVE_IMAGE" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="image/*"/>
</intent-filter>
</activity>
Here intent filter has custom action (this is important) this custom action is just some string, not app package or something (I'm using package name just because I like it).
Next, we need to add this activity to share menu list:
this will get bitmap Uri for sharing in other apps from ImageView
// Returns the URI path to the Bitmap displayed in specified ImageView
static public Uri getLocalBitmapUri(ImageView imageView) {
// Extract Bitmap from ImageView drawable
Drawable drawable = imageView.getDrawable();
Bitmap bmp = null;
if (drawable instanceof BitmapDrawable) {
bmp = ((BitmapDrawable) imageView.getDrawable()).getBitmap();
} else {
return null;
}
// Store image to default external storage directory
Uri bmpUri = null;
try {
File file = new File(Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_DOWNLOADS), "share_image_" + System.currentTimeMillis() + ".png");
file.getParentFile().mkdirs();
FileOutputStream out = new FileOutputStream(file);
bmp.compress(Bitmap.CompressFormat.JPEG, 80, out);
out.close();
bmpUri = Uri.fromFile(file);
} catch (IOException e) {
e.printStackTrace();
}
return bmpUri;
}
And this will collect all apps that can share image plus our save image intent
public void shareExcludingApp(Context ctx, PhotoView snapImage) {
// Get access to the URI for the bitmap
Uri bmpUri = ShareTool.getLocalBitmapUri(snapImage);
if (bmpUri == null) return;
List<Intent> targetedShareIntents = new ArrayList<>();
//get all apps which can handle such intent
List<ResolveInfo> resInfo = ctx.getPackageManager().queryIntentActivities(createShareIntent(bmpUri), 0);
if (!resInfo.isEmpty()) {
for (ResolveInfo info : resInfo) {
Intent targetedShare = createShareIntent(bmpUri);
//add all apps excluding android system and ourselves
if (!info.activityInfo.packageName.equals(getContext().getPackageName())
&& !info.activityInfo.packageName.contains("com.android")) {
targetedShare.setPackage(info.activityInfo.packageName);
targetedShare.setClassName(
info.activityInfo.packageName,
info.activityInfo.name);
targetedShareIntents.add(targetedShare);
}
}
}
//our local save feature will appear in share menu, intent action SAVE_IMAGE in manifest
Intent targetedShare = new Intent("com.my_app.random_text.SAVE_IMAGE"); //this is that string from manifest!
targetedShare.putExtra(Intent.EXTRA_STREAM, bmpUri);
targetedShare.setType("image/*");
targetedShare.setPackage(getContext().getPackageName());
targetedShare.putExtra("url", iSnapViewPresenter.getSnapUrlForSave());
targetedShare.putExtra("name", iSnapViewPresenter.getSnapNameForSave());
targetedShare.putExtra("description", iSnapViewPresenter.getSnapDescriptionForSave());
targetedShareIntents.add(targetedShare);
//collect all this intents in one list
Intent chooserIntent = Intent.createChooser(targetedShareIntents.remove(0),
"Share Image");
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS,
targetedShareIntents.toArray(new Parcelable[targetedShareIntents.size()]));
ctx.startActivity(chooserIntent);
}
I have two application A and B.
Application A
the following code I launch B Application for get Result from A application activity ..
String packageName = "com.cm.applicationb";
PackageManager manager = context.getPackageManager();
Intent i = manager.getLaunchIntentForPackage(packageName);
i.addCategory(Intent.CATEGORY_LAUNCHER);
i.putExtra("grand_total", "2500");
i.setAction(packageName);
startActivityForResult(i, REQUEST_DATA);
From Application A call onActivityResutl
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(requestCode==REQUEST_DATA)
if (resultCode == Activity.RESULT_OK) {
me=data.getStringExtra("Obj");
}
Toast.makeText(getApplicationContext(),me,Toast.LENGTH_LONG).show();
}
B Application setResult Data
Intent i=new Intent();
i.putExtra("Obj", "object");
setResult(Activity.RESULT_OK, i);
finish();
Ever retrun null data and resultcode from onActivityResult. How we can solve it? It is impossible get data onAcitivityResult from another applicaion setREsult. Anyone please help me for us. Thank you so much.
Remove finish() and call like this in B:
#Override
public void onBackPressed() {
Intent data = new Intent();
Bundle bundle = new Bundle();
bundle.putString("Obj", "Obj_Data");
data.putExtras(bundle);
setResult(Activity.RESULT_OK, data);
super.onBackPressed(); // this calls finish(); internally.
}
just add this line to your manifest.xml
<intent-filter>
<action android:name="android.intent.action.SEND" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="text/plain" />
</intent-filter>
for more detail, check this links that explain about how to receive data from other application
Here is the code, when selecting an image the app abruptly crashes :/ Please help, I cant progress further without this error being fixed.
Manifest
<activity
android:launchMode="singleTop"
android:name=".FoundMenu"
android:label="#string/app_name" >
<intent-filter>
<action android:name="com.guruguru2.lostnfound.FOUNDMENU" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
ImageView XML
<ImageView
android:id="#+id/imageView2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="0.71"
android:src="#drawable/abc_list_divider_mtrl_alpha" />
.java file
Button pickImageButton = (Button)findViewById(R.id.pick_image_button);
private static final int PICK_IMAGE = 100;
private ImageView imageView2;
pickImageButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
openGallery();
}
});
}
private void openGallery() { //opens the gallery
Intent gallery =
new Intent(Intent.ACTION_PICK,
android.provider.MediaStore.Images.Media.INTERNAL_CONTENT_URI);
startActivityForResult(gallery, PICK_IMAGE);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK && requestCode == PICK_IMAGE) {
Uri imageUri = data.getData();
imageView2.setImageURI(imageUri);
}
}
LogCat
E/AndroidRuntime(1083): java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=100, result=-1, data=Intent { dat=content://media/external/images/media/16 }} to activity {com.guruguru2.lostnfound/com.guruguru2.lostnfound.FoundMenu}: java.lang.NullPointerException
The main goal here is to select an image from the gallery, and simply show it. I can post more logcat if needed, there is a lot more, this error seemed the most fatal though.
You might try to change the intent from INTERNAL_CONTENT_URI to EXTERNAL_CONTENT_URI.
Check this stackoverflow url for further information on this issue:
Android get image from gallery into ImageView
Here is the code, when selecting an image the app abruptly crashes
You forgot to set the view to the ImageView do it as follows :
imageView2 = (ImageView)findViewById(R.id.ImageView2);
Then you are able to set the image to your ImageView, it doesn't mean that it solves your problem, but it's the MAIN error in your code as I can see.
In my app, I model Lists of items. In MainActivity, I see ListView containing Lists. I can click on each list to see its items (DisplayListActivity). On DisplayListActivity, I have button in the ActionBar to display the list properties. This launches the third activity (EditListPropertiesActivity).
Main
| ^
V |
DisplayListActivity (listId is passed with Intent, default=1)
| ^
V |
EditListPropertiesActivity (listId is passed with Intent, default=1)
The problem appears, when I select List id=2 on the MainActivity, and then I select the properties button on the DisplayListActivity. Once I am done with the EditListPropertiesActivity, i click '<' (back) on the ActionBar: .
I return to the DisplayListActivity, but instead of going back to the list id=2, I see the list with id=1 (which is default).
How to pass the ListId back form EditListPropertiesActivity to the DisplayListActivity?
startActivityForResult and return the id - would work, but I see it ugly
use the SharedPreferences and store sth like lastVisitedList - ugly
store the lastVisitedList information in the db - even uglier
What is the usual solution for that problem?
Code snippets below.
MainActivity
public class MainActivity extends Activity {
...
listView.setOnItemClickListener(
new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
MetaList mlist = (MetaList) listView.getItemAtPosition(i);
final Intent intent;
intent = new Intent(getApplicationContext(), DisplayListActivity.class);
intent.putExtra(META_LIST_SELECTED, mlist.getId());
startActivity(intent);
}
}
);
...
DisplayListActivity
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.single_list);
intent = getIntent();
metaListId = intent.getLongExtra(MainActivity.META_LIST_SELECTED, 1); //read the data or take 1 as default
...
//start the third activity
final Intent intent;
intent = new Intent(getApplicationContext(), EditListPropertiesActivity.class);
intent.putExtra(META_LIST_SELECTED, metaListId);
startActivity(intent);
....
EditListPropertiesActivity
public class EditListPropertiesActivity extends Activity {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.edit_list_parameters);
getActionBar().setDisplayHomeAsUpEnabled(true); //this enables the '<' (back) button
intent = getIntent();
metaListId = intent.getLongExtra(DisplayMetaListActivity.META_LIST_SELECTED, 1);
...
Manifest
<application>
<activity
android:name=".MainActivity">
</activity>
<activity
android:name="com.example.tutorial1.DisplayListActivity"
android:parentActivityName="com.example.tutorial1.MainActivity" >
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="com.example.tutorial1.MainActivity" />
</activity>
<activity
android:name="com.example.tutorial1.EditListPropertiesActivity"
android:parentActivityName="com.example.tutorial1.DisplayListActivity" >
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="com.example.tutorial1.DisplayListActivity" />
</activity>
</application>
try this to finish an activity
Intent intent = new Intent();
intent.putExtra(EXTRA, value);
setResult(RESULT_OK, output);
finish();
and this for getting the result in the previous activity
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(data.getExtras().containsKey(EXTRA)){
// do stuff with data from finished activity
String bla = data.getStringExtra(EXTRA)
}
}
EDIT: read comments! need to use startActivityForResult
try to call finish(); that you should call on destroy of the current activity and display the previous activity.
I have found the solution that works. I post it here, because it is cleaner (in my opinion) and different than the other proposed. I set the launch mode of the second activity to singleTask in the manifest file: android:launchMode="singleTask"
...
<activity
android:name="com.example.tutorial1.DisplayListActivity"
android:label="Meta List"
android:parentActivityName="com.example.tutorial1.MainActivity"
android:launchMode="singleTask">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="com.example.tutorial1.MainActivity" />
</activity>
...
If there is a better solution for the stated problem, I am open for discussion :)