android studio intent inside intent crash - android

So I have two activities, let's call them A and B, activity A have a text input and a button, which call to activity B with an intent method:
and I have activity B which have also intent to the camera application:
ImageView photo;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.b);
TextView textView = findViewById(R.id.textView);
Button buttonCapture = findViewById(R.id.buttonCapture);
photo = findViewById(R.id.photo);
buttonCapture.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent1 = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(intent1, 0);
}
});
}
#TargetApi(Build.VERSION_CODES.KITKAT)
#Override
protected void onActivityResult(int requestCode, int resultCode, #Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
Bitmap bitmap = (Bitmap) (data != null ? requireNonNull(data.getExtras()).get("data") : null);
photo.setImageBitmap(bitmap);
}
and when I launch this in a simulator, I get the first A activity fine, click on the button, it open activity B, I press the button again, and it returns me to activity A or crash(random?)
my manifest file:
package="com.example.user.app">
<uses-permission android:name="android.permission.CAMERA"/>
<uses-feature android:name="android.hardware.camera" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity android:name=".A">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".B">
</activity>
</application>
with the exception:
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.user.app, PID: 18441
java.lang.SecurityException: Permission Denial: starting Intent { act=android.media.action.IMAGE_CAPTURE cmp=com.android.camera2/com.android.camera.CaptureActivity } from ProcessRecord{296747c 18441:com.example.user.app/u0a88} (pid=18441, uid=10088) with revoked permission android.permission.CAMERA

ok, I see...
Starting Android 6 (API 23), if your app has CAMERA permission declared in the manifest, it needs that CAMERA permission to be GRANTED in order to access ACTION_IMAGE_CAPTURE etc... too (which normally do not require the CAMERA permission on their own). If not, then it automatically raises a SecurityException.
do like below!!!
1- If you only need ACTION_IMAGE_CAPTURE etc..
Remove the CAMERA permission from manifest and you would be fine
2- If you need CAMERA permission too
Check for CAMERA permission at runtime and only start the intent when the permission is available

1) it maybe happens when you don't declare your B activity in manifests!!!
2)remove final before defining EditText and try again!!!
if you send your logs, I can help you better...

Related

Activity not starting when the icon is clicked

I've began working on a simple Android project recently, but it looks like I just cannot get it to work. I have a main Activity (It has #style/Invisible parameter) which checks if my service is running and starts it if it's not. Also, before the check takes place it starts another activity for result. The activity is expected to return the user's username and password to allow the app to login to the system. The problem is that when I install the app on my phone it works fine, but next time I open the app nothing happens. I have to reinstall it.
Here's the main Activity:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE);
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
Intent intent = new Intent(this, LoginGrabber.class);
startActivityForResult(intent, 100);
if(isMyServiceRunning()==false)
{
startService(new Intent(getApplicationContext(), MyService.class));
Log.i("com.connect","startService");
}
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data){
if(requestCode == 100){
if(resultCode == RESULT_OK){
String username = data.getStringExtra("Username");
String password = data.getStringExtra("Password");
//TODO Send to server
Toast.makeText(this, "Username: " + username + " Password: " + password, Toast.LENGTH_LONG);
}
}
}
private boolean isMyServiceRunning() {
ActivityManager manager = (ActivityManager) getApplicationContext().getSystemService(Context.ACTIVITY_SERVICE);
for (RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
if (MyService.class.getName().equals(service.service.getClassName())) {
return true;
}
}
return false;
}
LoginGrabber Activity:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login_grabber);
}
public void onSendData(View view){
Intent intent = new Intent();
intent.putExtra("Username", ((TextView) findViewById(R.id.email)).getText());
intent.putExtra("Password", ((TextView) findViewById(R.id.password)).getText());
setResult(RESULT_OK, intent);
finish();
}
Here's the Manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.app.test"
android:versionCode="2"
android:versionName="2.0">
<uses-sdk
android:minSdkVersion="10"
android:targetSdkVersion="18" />
<supports-screens
android:largeScreens="true"
android:resizeable="true"
android:xlargeScreens="true" />
<uses-permission
android:name="android.permission.INTERNET"
android:required="true" />
<application
android:icon="#drawable/launcher"
android:label="#string/app_name"
android:theme="#style/Invisible">
<activity
android:name="com.connect.Main"
android:excludeFromRecents="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
<service
android:name="com.connect.MyService"
android:enabled="true"
android:exported="true" />
<activity
android:theme="#style/AppTheme"
android:name="com.connect.LoginGrabber"
android:label="#string/title_activity_login_grabber" />
</application>
</manifest>
What am I doing wrong?
Thanks for your help!
OK! I found the problem! The problem was that my application was crashing as soon as the service was started because I was testing the app without internet and without handling errors that were thrown when there was no internet available.
Just had to turn WiFi on, that's it!

no activity found to handle

I am getting error while click on list item
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
String selected =((TextView)view.findViewById(R.id.no)).getText().toString();
Toast toast=Toast.makeText(getApplicationContext(), selected, Toast.LENGTH_SHORT);
toast.show();
try {
Intent in=new Intent(Intent.ACTION_CALL,Uri.parse(selected));
startActivity(in);
} catch (SecurityException e) {
Log.e("PERMISSION_EXCEPTION","PERMISSION_NOT_GRANTED");
}
}
An error is Message which i am getting in Logcat
01-06 10:37:19.091 19537-19537/? E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.sairamkrishna.myapplication, PID: 19537
android.content.ActivityNotFoundException: No Activity found to handle Intent { act=android.intent.action.CALL dat=1234 567 89 }
at android.app.Instrumentation.checkStartActivityResult(Instrumentation.java:1856)
at android.app.Instrumentation.execStartActivity(Instrumentation.java:1552)
*Manifest file here i have added permission and MainActivity and intent filter
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.sairamkrishna.myapplication">
<uses-permission android:name="android.permission.READ_CONTACTS" />
<uses-permission android:name="android.permission.CALL_PHONE" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
You are getting
android.content.ActivityNotFoundException: No Activity found to handle
Intent { act=android.intent.action.CALL dat=1234 567 89 }
All activities must be declared in the AndroidManifest.xml. Without the declaration, ActivityNotFoundException is thrown.
Make sure activity is added in AndroidManifest & Intent.ACTION_CALL calling properly .
You can share your manifest .
Did you add this ?
<uses-permission android:name="android.permission.CALL_PHONE"></uses-permission>
You can try (your selected text must be format: tel:xxxxxxxxx)
Intent in = new Intent(Intent.ACTION_DIAL,Uri.parse(selected));
startActivity(in);
Remember add this permission:
<uses-permission android:name="android.permission.CALL_PHONE" />
First of all since you are using implicit intent , you do not need to specify call permission in manifest.
Whenever you are calling any implicit intent if it doesn't find any matching activity which can perform given action , then this exception occurs.
You can handle that by using following code.
Intent intent=new Intent(Intent.ACTION_CALL,Uri.parse(selected));
List<ResolveInfo> list=new PackageManager().queryIntentActivities(intent ,0);
if(list.size()>0){
Intent chooser = Intent.createChooser(intent, "title");
startActivity(chooser);
}else{
//Show toast or alert saying no activities available to perform specified action.
}
Important thing is to make Phone Call data format is like this tel:your_number :)
Intent in=new Intent(Intent.ACTION_CALL, Uri.parse("tel:"+selected));

Android permission for camera and Internet

In Android, I remember that it was mandatory to request permission(s) to use the camera or to access the Internet in an app.
But I did a small test in which I did not request any of the above permissions and I expected my test app to crash and burn.
But this did not happen!!
I was able to use the camera and access the Internet without requesting for permissions, and I've tested on 3 devices, all with different versions of Android.
Here is the code:
public class MainActivity extends Activity implements View.OnClickListener
{
private int cameraCode = 0;
private Button start_cam;
private Button start_internet;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
start_cam = (Button) findViewById(R.id.camera);
start_internet = (Button) findViewById(R.id.internet);
start_cam.setOnClickListener(this);
start_internet.setOnClickListener(this);
}
#Override
public void onClick(View v)
{
switch(v.getId())
{
case R.id.camera:
Intent intent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(intent, cameraCode);
break;
case R.id.internet:
Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("http://www.imdb.com"));
startActivity(browserIntent);
break;
}
}
}
the manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.permissions.linux.android">
<uses-sdk
android:minSdkVersion="10"
android:targetSdkVersion="16" />
<application
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name">
<activity
android:name="com.permissions.linux.androi.android.MainActivity"
android:label="#string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
The question is, why didn't it crash?
I was able to use the camera and access the Internet without requesting for permissions
No, you were not. You were able to ask other applications "to use the camera and access the Internet" on your behalf. Your application did not directly use the camera, and your application did not directly access the Internet. The other applications that you linked to will need the CAMERA and INTERNET permissions to do their jobs. While sometimes you may need to hold a certain permission even to get a third-party app to do something for you, that is not needed to take a picture or view a Web page.

onResultActivity is called immediately after startActivyForResult

In my main activity i have this code:
noConnectionButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
startActivityForResult(new Intent(Settings.ACTION_WIRELESS_SETTINGS), SET_CONNECTION);
}
});
in the onCreate method. Then:
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if(requestCode == SET_CONNECTION){
checkConnection();
}
}
So what I want to do is to start the settings activity in a way that the user can switch on wireless or data connection.
My problem is that the onActivityResult is called prematurely!!! so I want it to be called only after the user backs to my activity.
any suggestion??
here the manifest
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="it.polimi.metalnews"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="13"
android:targetSdkVersion="19" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<application
android:allowBackup="true"
android:icon="#drawable/launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name="it.polimi.metalnews.MainActivity"
android:label="#string/app_name"
android:theme="#android:style/Theme.NoTitleBar.Fullscreen" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name="it.polimi.metalnews.HomeActivity"
android:label="#string/title_activity_home" >
</activity>
<activity
android:name="it.polimi.metalnews.NewsActivity"
android:label="#string/title_activity_news" >
</activity>
<activity
android:name="it.polimi.metalnews.AlbumActivity"
android:label="#string/title_activity_album" >
</activity>
<activity
android:name="it.polimi.metalnews.ContestActivity"
android:label="#string/title_activity_contest" >
</activity>
</application>
follow this process:
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
// Check which request we're responding to
if (requestCode == PICK_CONTACT_REQUEST) {
// Make sure the request was successful
if (resultCode == RESULT_OK) {
// The user picked a contact.
// The Intent's data Uri identifies which contact was selected.
// Do something with the contact here (bigger example below)
}
}
}
use below link for further detail:
http://developer.android.com/training/basics/intents/result.html
In onActivity result first check if the result is came from the action is OK or not by comparing your result code to RESULT_OK like:
if (resultCode == RESULT_OK) {
// You successfully got back then do what ever you want.
//Then you can check you particular data according to your request.
}
Because there is no reason for going deep if the result is not ok. Every system service will result in RESULT_OK or RESULT_CANCEL if canceled by user.
I don't think there is anything wrong with intent declaration but i read this kind of article link it explains your problem in a better manner
It is due to the Activity is SingleTask and whenever it is called it reports the result.

Getting Permission error java.lang.SecurityException: Permission Denial on 3.x Android devices while getting email attachment name

I am facing issue in opening Email in MYApp when I made its launch mode to "singleInstance".
I have attached sample Android project which reads file name from email attachment and displays it on screen.
Works fine in case of onCreate but throws error in onNewIntent when apps launch mode is singleInstance.
Launchmode.java
package your.namespace.launchmode;
public class LaunchModeActivity extends Activity {
private static final int OPEN_ACT = 2;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
String name = getAttachmetName(getIntent());
if(null != name)
{
TextView textv = (TextView) findViewById(R.id.attachmentnm);
textv.setText(name);
}
}
#Override
protected void onNewIntent(Intent savedInstanceState)
{
super.onNewIntent(savedInstanceState);
String name = getAttachmetName(savedInstanceState);
if(null != name)
{
TextView textv = (TextView) findViewById(R.id.attachmentnm);
textv.setText(name);
}
}
private String getAttachmetName(Intent intent) {
final Uri documentUri = intent.getData();
if(null != documentUri){
final String uriString = documentUri.toString();
String documentFilename = null;
final int mailIndexPos = uriString.lastIndexOf("/attachments");
if (mailIndexPos != -1) {
final Uri curi = documentUri;
final String [] projection = new String[] {OpenableColumns.DISPLAY_NAME};
final Cursor cursor = getApplicationContext().getContentResolver().query(curi, projection, null, null, null);
if (cursor != null) {
final int attIdx = cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME);
if (attIdx != -1) {
cursor.moveToFirst();
documentFilename = cursor.getString(attIdx);
}
cursor.close();
}
}
return documentFilename;
}
return null;
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// TODO Auto-generated method stub
super.onActivityResult(requestCode, resultCode, data);
if((resultCode == RESULT_OK) && (requestCode == OPEN_ACT))
{
Log.d("LaunchMode", "Second activity returned");
}
}
}
AndroidManifest
<?xml version="1.0" encoding="UTF-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="your.namespace.launchmode"
android:versionCode="1"
android:versionName="1.0" >
<uses-permission android:name="com.google.android.gm.permission.READ_GMAIL"/>
<uses-permission android:name="com.google.android.gm.permission.WRITE_GMAIL"/>
<uses-permission android:name="com.google.android.providers.gmail.permission.READ_GMAIL"/>
<uses-permission android:name="com.google.android.providers.gmail.permission.WRITE_GMAIL"/>
<uses-sdk android:minSdkVersion="8" />
<application
android:icon="#drawable/ic_launcher"
android:label="#string/app_name" >
<activity
android:label="#string/app_name"
android:launchMode="singleInstance"
android:name=".LaunchModeActivity" >
<intent-filter >
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter >
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<!-- docx -->
<data android:mimeType="application/vnd.openxmlformats-officedocument.wordprocessingml.document" />
<!-- xlsx -->
<data android:mimeType="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" />
<!-- pptx -->
<data android:mimeType="application/vnd.openxmlformats-officedocument.presentationml.presentation" />
<data android:mimeType="application/vnd.ms-excel" />
<data android:mimeType="application/msword" />
<data android:mimeType="application/vnd.ms-powerpoint" />
<data android:mimeType="text/plain" />
</intent-filter>
</activity>
</application>
</manifest>
Steps to reproduce
1)Install apk on device.
2)Go to gmail native app on device, open any attachment(office document) to view.
3)Choose LaunchMode app to complete action.
4)LaunchMode app will display file name on screen.
This works fine for first time (onCreate flow) but when this app is switch in background and again I try 2,3,4 steps.. app crashes with error
E/DatabaseUtils(30615): java.lang.SecurityException: Permission Denial: reading com.google.android.gm.provider.MailProvider uri content://gmail-ls/qoconnect#gmail.com/messages/5/attachments/0.2/BEST/false from pid=32657, uid=10058 requires com.google.android.gm.permission.READ_GMAIL
E/DatabaseUtils(30615): at android.content.ContentProvider$Transport.enforceReadPermission(ContentProvider.java:309)
E/DatabaseUtils(30615): at android.content.ContentProvider$Transport.bulkQuery(ContentProvider.java:178)
E/DatabaseUtils(30615): at android.content.ContentProviderNative.onTransact(ContentProviderNative.java:111)
E/DatabaseUtils(30615): at android.os.Binder.execTransact(Binder.java:339)
E/DatabaseUtils(30615): at dalvik.system.NativeStart.run(Native Method)
D/AndroidRuntime(32657): Shutting down VM
I need to fix this as, I need to have single instance of Application and should get email attachment name too.
Please let me know If I am missing something here.
My question here is why it work in flow of onCreate and it wont work in case of onNewIntent
Note:
1)Works fine with 2.x phones
2) Works fine with Single top launch mode.
3) Some updates on Gmail app.link here:
You likely got a URI permission to read the file name when you received the intent and aren't using the permissions that you requested (READ_GMAIL and WRITE_GMAIL). The URI permission is valid only until your application finish()es, so you won't have it when you try to resume.
That's consistent with your experiences - it works when the intent is fresh, but not old ones. I think that WRITE_GMAIL is a signature permission and I am guessing that READ_GMAIL is as well. In that case, there is not much you can do. READ_ATTACHMENT might be a more appropriate permission for you to request.
More on URI permissions: http://developer.android.com/guide/topics/security/permissions.html#uri
Try removing the uses-permission tags from your manifest and see if you have the same experience. You can also try to examine the intent when you receive it by checking its flags.
checkCallingOrSelfUriPermission(documentUri , Intent.FLAG_GRANT_READ_URI_PERMISSION)
If you get 0 returned, you have been using URI permissions.
Like skoke said, you can no longer read from GMail if the intent that gave your permission is not fresh, i.e., it must be the original activity intent. If your intent is from onNewIntent then it probably won't succeed.
My solution isn't beautiful but seems to be working. In my onResume I called a custom function to see if I could access the Gmail content. If not, I showed the user a message and asked them to close the app and try again. Hey, at least it doesn't crash.

Categories

Resources