Android securityException and user contacts - android

I have am wrighting an android app and as a part of the app I would like the user to be able to see, select,and modify the user contacts. My main activity extends the TabActivity for usability reasons(from the users side). So in a tab i would like to show user contacts i have done that with this code: mTabHost.addTab(mTabHost.newTabSpec("tab_test2").setIndicator("Contacts").setContent(new Intent(Intent.ACTION_PICK, People.CONTENT_URI)));
that uses the default phone contact activity. my android manifest is: `
<uses-permission android:name="android.permission.READ_CONTACTS"/>
<uses-permission android:name="android.permission.READ_OWNER_DATA"/>
<application android:icon="#drawable/icon" android:theme="#android:style/Theme.NoTitleBar">
<activity android:name=".WaveCally"
android:label="#string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".streamer"
android:label="#string/stream">
</activity>
</application>
<uses-sdk android:minSdkVersion="4" />
` but I keep getting a security exception in my log and the activity crashes. any ideas?
Also as I mentioned I would like to modify the contacts (mostly add some extra fields), to do that I have to get the contantprovider and in every contact add the extra fields? would those extra fields be available if I then pick a contact from the above mentioned activity?

You need to declare in the application Manifest that your application is going to access the Contacts. (android.permission.READ_CONTACTS)
This is what you need to do:
http://developer.android.com/guide/topics/manifest/uses-permission-element.html
Basically, add the following line in your app manifest (right after opening the manifest tag):
<uses-permission android:name="android.permission.READ_CONTACTS" />

Related

How to stop an activity to be accessed from another app?

In my app I have two activities:
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".SecondActivity"/>
So my SecondActivity can be accessed from another app. I think it's a security issue, so how can I stop this? Is this somehow related with exported setup?
Within three steps you can do it.
define a permission (which is only available to applications having your signature)
define that your application uses your defined permission
require that permission for the activities you want protected. (Be careful to not require it for your main launch activity).
<!-- to define a permission -->
<permission
android:protectionLevel="signature"
android:name="com.example.MYPERMISSION"/>
<uses-permission android:name="com.example.MYPERMISSION" />
<!-- to define an activity which can only be started through internal code -->
<activity android:name="..."
android:permission="com.example.MYPERMISSION" >
...
</activity>
android:exported = false in AndroidManifest inside activity tag should do the work

Android manifest for USBAccesory

I am making an app that communicates with a piece of usb hardware made by my company (this is the only app allowed to talk to the usb accessory, it's not a public api). I am having difficulties setting up the proper launch modes in the manifest.
There are three components to the app: the main activity, a login activity, and the USBService.
I'm assuming the intent for the main goes to the login activity, and the intent for the usb goes to the USBService, but I am not sure if I do this, will this start the service if the app is not running? More over, if it does, how do I fetch an already existing service?
What type of structure should I be looking at for the manifest file? (specifically, intent-filters, and appropriate launch modes... I've read a few documents about the launch modes but I am still not sure I quite understand... There should only ever be at most one instance of each activity/service, and they need to communicate together.
edit: it is not necessary for communications to start before the app is open, nor is it necessary to launch the app automatically when the usb is connected.
edit: my manifest as it stands, looks like:
<uses-feature android:name="android.hardware.usb.accessory" />
<uses-sdk
android:minSdkVersion="15"
android:targetSdkVersion="17" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<application
android:icon="#drawable/ic_launcher"
android:label="#string/app_name" >
<activity
android:name="mainpackage.MainActivity"
android:label="#string/app_name"
android:launchMode="singleTop">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<action android:name="android.hardware.usb.action.USB_ACCESSORY_ATTACHED" />
</intent-filter>
<meta-data
android:name="android.hardware.usb.action.USB_ACCESSORY_ATTACHED"
android:resource="#xml/accessory_filter" />
</activity>
<activity
android:name="mainpackage.LoginActivity"
android:label="#string/title_activity_login"
android:windowSoftInputMode="adjustResize|stateVisible" >
</activity>
<service android:name="updater.USBService"
android:exported="false" >
<!--
-->
</service>
</application>
in your manifest add
<manifest ...>
<uses-feature android:name="android.hardware.usb.host" />
<uses-sdk android:minSdkVersion="12" />
In this case, the following resource file should be saved in res/xml/device_filter.xml and specifies that any USB device with the specified attributes should be filtered:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<usb-device vendor-id="1234" product-id="5678" class="255" subclass="66" protocol="1" />
</resources>
Hope this help.
Your manifest looks good,
I think you make a good choice for putting the intent-filter "android.hardware.usb.action.USB_ACCESSORY_ATTACHED" in the mainActivity and start the application in this activity,
and again I think it's a good choice to start your mainActivity in SingleTop launch mode,
because if an instance of the mainActivity already exists at the top of the current task, the system going to launch this activity, no new instance of this activity will be created.
For a best understanding of the different launch mode available in android,
I think this link may help you :
http://www.intridea.com/blog/2011/6/16/android-understanding-activity-launchmode
To make a long story short I think you'll be all set with this manifest as is.
To Use Android Devices min SDK version should be set to 12 and need to declare following line in AndroidManifest.xml file
<>
<uses-sdk android:minSdkVersion="<version>" />
...
<application>
<uses-library android:name="com.android.future.usb.accessory" />
<activity ...>
...
<intent-filter>
<action android:name="android.hardware.usb.action.USB_ACCESSORY_ATTACHED" />
</intent-filter>
<meta-data android:name="android.hardware.usb.action.USB_ACCESSORY_ATTACHED"
android:resource="#xml/accessory_filter" />
</activity>
</application>

App refuses to connect to Parse backend

I am working on an app called TobaccoRoad that uses a library project called BestApproach. It uses a Parse backend to display custom generated content and handle push notifications. Everything was working pretty alright until a few days ago, when I must have messed up some settings somewhere and it no longer seems to be making the connection to the parse systems. I'm quite sure it's a local issue, because my second tester phone, which has not had updated code pushed to it in a few days, is still receiving notifications and can view that custom content.
The weird thing is, even after clearing my workspace and starting fresh from the (definitely good) code my employer gave me, and following all the tutorials and troubleshooting guides on Parse.com (see https://parse.com/docs/push_guide#installations/Android; https://parse.com/tutorials/android-push-notifications) I'm still not connecting to Parse. I haven't made any significant changes that I can recall, so I'm at a loss as to what might be causing this.
I know it's not an issue of a bad applicationID or clientKey, because even substituting random strings into the Parse.initialize call gave the same results, and a logcat error about not being able to authenticate.
Here are the relevant bits from my manifest files, first for the library project...
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.bestapproach.lib"
android:versionCode="8"
android:versionName="1.6.1">
<uses-sdk android:minSdkVersion="7" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.CALL_PHONE"></uses-permission>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"></uses-permission>
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<application android:icon="#drawable/app_icon" android:label="#string/app_name"
android:theme="#style/Theme.BA" >
<activity android:name="com.bestapproach.lib.SplashActivity"
android:label="#string/app_name"
android:screenOrientation="portrait"
android:configChanges="orientation"
android:theme="#style/Theme.BA.Splash">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<!--Declarations for all of my Activities...-->
<service android:name="com.parse.PushService" />
<receiver android:name="com.parse.ParseBroadcastReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.intent.action.USER_PRESENT" />
</intent-filter>
</receiver>
</application>
</manifest>
And the manifest is exactly the same for my dependent project, with the exception of where I define a custom receiver at the end:
<service android:name="com.parse.PushService" />
<receiver android:name="com.parse.ParseBroadcastReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.intent.action.USER_PRESENT" />
</intent-filter>
</receiver>
<receiver android:name="com.bestapproach.lib.MyCustomReceiver">
<intent-filter>
<action android:name="com.bestapproach.lib.UPDATE_STATUS" />
</intent-filter>
</receiver>
And here's the code for the onCreate() method in my main activity (SplashActivity) where the Parse service is initialized:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_splash);
String parseClientId = getString(R.string.parse_client_id);
String parseAppId = getString(R.string.parse_app_id);
//debug output
Log.v("parse should be initializing...", parseAppId+" "+parseClientId);
if (!("".equals(parseClientId) || "".equals(parseAppId))) {
Parse.initialize(this, parseAppId, parseClientId);
PushService.subscribe(this, "", MenuActivity.class);
PushService.setDefaultPushCallback(this, SplashActivity.class);
ParseInstallation.getCurrentInstallation().saveInBackground();
ParseAnalytics.trackAppOpened(getIntent());
final Activity a = this;
// Fetches content if it doesn't exist.
StoreManager sm = StoreManager.getInstance(a);
ParseStoreManager psm = ParseStoreManager.getInstance(a);
return;
}
}
Suggestions I've found that seem like they may be on track with what I need include running Parse.initialize() in the onCreate() of every activity, which I don't really want to do as there are a lot of them and that would be a lot of duplicated code, or generating an Application object and running it from there. Everything I've tried in relation to that has ended up breaking once I add it to my manifest file, due to TobaccoRoad's dependencies on the library project.
I know, it's a lot to dig through, but any suggestions would be appreciated. Thanks everybody.
Possible fix:
Change this line
if (!("".equals(parseClientId) || "".equals(parseAppId))) {
Parse.initialize(this, parseAppId, parseClientId);
to this:
if (!("".equals(parseClientId) || "".equals(parseAppId))) {
Parse.initialize(SplashActivity.this, parseAppId, parseClientId);
the issue is that
ParseAnalytics.trackAppOpened(getIntent());
accepts the intent from that activity from your SplashActivity and from the application scope
Also, you initialize parse from the activity which we generally don't do.
We try initialize parse from the Application class so it has the context of the Application scope and not of the Activity Scope.
I recommend you to create an Application class and include the parse code in the onCreate of the Application...which you would need to do only once.
Or, you can create some BaseActivities and make all your activities in the application extend to that. This will save you from writing duplicate code...this is just in case you are bound not to create an Application class.
Pardon me for anything wrong...I am new in answering.

Selecting default action on Android

I am trying to build an application that would replace a default action on Android. The problem is that when action should be performed i get "Select Action" dialog with no checkbox to select it as default. I think i should be getting "Complete Action Using" dialog (which in turn has the checkbox). I do not understand how I can make Android to offer me the "Complete ..." dialog. My manifest file is as:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="si.cetrtapot.mobiris"
android:versionName="1.0"
android:versionCode="1" >
<uses-sdk android:minSdkVersion="10" />
<uses-permission android:name="android.permission.NFC" />
<uses-feature android:name="android.hardware.nfc"
android:required="true" />
<application android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:debuggable="true" >
<activity android:name=".ReadTagActivity"
android:label="#string/app_name"
android:screenOrientation="portrait" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<action android:name="android.nfc.action.TECH_DISCOVERED" />
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
<meta-data android:name="android.nfc.action.TECH_DISCOVERED"
android:resource="#xml/nfc" />
</activity>
</application>
</manifest>
Can anybody tell me what is wrong?
The way intent-filters work is that the PackageManager has all these applications registered with it via the Manifest that is found per application. Specifically when an application falls un a certain Intent-Filter, it will then be added to the list of applications that have those kinds of Intent-Filters declared in their Manifest.
For instance say my application, handles the: Intent.ACTION_SEND this means that my application will show up in the list of application that hand particular action. Which would include, the default MMS/SMS application and any other applications the user has that has this, including MY application if the user has it installed.
You should begin by understanding what "default action" even means. Understanding this will help you how to solve your problem.
For your reference:
Intent
Intent.CATEGORY_DEFAULT
I do not believe that anything is wrong. I don't believe NFC intents were meant to have a default app unless you have very specific intent filtering for Ndef formatted cards. I did this for my job because we wanted just our app to pop up with our tag. Otherwise it would just be in a list all the time (which is annoying).

How to hide application icon from the Android Desktop?

I defined an application which is only used from my other application. So I would like to hide the icon of this application, so that the user can't see it on the desktop of his phone (or how do you call the thing where all apps are listed?). My manifest file looks the following way:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="xyz.games.pacman.controller"
android:versionCode="1"
android:versionName="1.0">
<uses-permission android:name="android.permission.BLUETOOTH"/>
<application android:icon="#drawable/icon" android:label="#string/app_name">
<activity android:name=".PacmanGame"
android:label="#string/app_name"
android:screenOrientation="portrait">
<intent-filter>
<action android:name="pacman.intent.action.Launch" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
<receiver android:name="xyz.games.pacman.network.MessageListener">
<intent-filter>
<action android:name="xyz.games.pacman.controller.BROADCAST" />
</intent-filter>
</receiver>
</application>
<uses-sdk android:minSdkVersion="7" />
</manifest>
I already read this question:
How to hide an application icon in Android emulator?
but if i just remove the line
<category android:name="android.intent.category.DEFAULT" />
in my manifest, the activity isn't working at all (ActivityNotFoundException in the calling activity).
Any hints how to solve this problem? I already tried android.intent.category.EMBEDDED but this doesn't work too.
In the Internet I found CommonsWare answer http://osdir.com/ml/Android-Developers/2010-06/msg03617.html that it can be done using PackageManager. Unfortunately, it isn't explained how exactly and I couldn't find a solution by browsing the PackageManager API.
You need to create a custom intent filter and then create an intent which uses that filter.
For example, in my Funky Expenses application external apps can add transactions. This is achieved by the manifest for Funky Expenses containing
<activity android:name="com.funkyandroid.banking.android.ExternalEntryActivity">
<intent-filter>
<action android:name="com.funkyandroid.action.NEW_TRANSACTION" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
and then external application can access my activity in the following way;
Intent launchIntent = new Intent();
launchIntent.setAction("com.funkyandroid.action.NEW_TRANSACTION");
... code to set parameters to be passed to activity ...
startActivity(launchIntent);
Pay special attention to the setAction call which sets the correct intent.
why would you write an actual (executable) second application that merely exists to do something when it receives sth from another app?
i'd suggest, you implement this "app" as a service (remote or local). this service would then run in the background and do stuff for you and there won't be any icons to be displayed on the screen for it...
if neccessary, you can implement this service to be remote, meaning it runs in a totally different process then the first app. and: you actually can communicate via broadcast intents as you seem to do by now so you won't need to change your first app...
Try removing the intent-filter and instead of trying to launch the 2nd activity with the filter lounch directly the activity:
Intent second = new Intent(context, xyz.games.pacman.controller.PacmanGame.class);
startActivity(second);
You must remove the whole <intent-filter>, not just the <category>

Categories

Resources