When clicking the "share" button after opening a picture in my gallery, I have the option to share (or open) the picture with another app.
Think for example about Instagram or Snapchat.
How does this work and how would I do this using ADB? I am slightly familiar with intents and deep linking.
However, any variation I try on the examples given either returns:
Error: Activity not started, unable to resolve Intent
Or when trying to use an intent listed in the Snapchat XML file, embedded in the apk, such as:
adb shell am start -a android.intent.action.SEND -t image/* -d "file:///sdcard/_tmp/1.jpg" com.snapchat.android
It doesn't open the image.
Here's the XML file.
<?xml version="1.0" encoding="utf-8"?>
<manifest android:installLocation="auto" package="com.snapchat.android" platformBuildVersionCode="25" platformBuildVersionName="7.1.1" xmlns:android="http://schemas.android.com/apk/res/android">
<uses-sdk android:minSdkVersion="17" android:targetSdkVersion="22" />
<uses-feature android:name="android.hardware.camera" android:required="false" />
<uses-feature android:name="android.hardware.camera.any" android:required="true" />
<permission android:name="com.snapchat.android.permission.C2D_MESSAGE" android:protectionLevel="signature" />
<uses-permission android:name="com.snapchat.android.permission.C2D_MESSAGE" />
<supports-screens android:anyDensity="true" android:largeScreens="true" android:normalScreens="true" android:smallScreens="true" android:xlargeScreens="true" />
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.READ_CONTACTS" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.FLASHLIGHT" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.READ_PROFILE" />
<uses-permission android:name="android.permission.RECEIVE_SMS" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
<uses-permission android:name="com.android.vending.BILLING" />
<uses-feature android:glEsVersion="0x20000" android:required="true" />
<uses-feature android:name="android.hardware.camera.autofocus" android:required="false" />
<uses-feature android:name="android.hardware.camera.flash" android:required="false" />
<uses-feature android:name="android.hardware.camera.front" android:required="false" />
<uses-feature android:name="android.hardware.telephony" android:required="false" />
<uses-feature android:name="android.hardware.microphone" android:required="false" />
<uses-feature android:name="android.hardware.location" android:required="false" />
<uses-feature android:name="android.hardware.location.gps" android:required="false" />
<uses-permission android:name="com.sec.android.provider.badge.permission.READ" />
<uses-permission android:name="com.sec.android.provider.badge.permission.WRITE" />
<uses-permission android:name="com.htc.launcher.permission.READ_SETTINGS" />
<uses-permission android:name="com.htc.launcher.permission.UPDATE_SHORTCUT" />
<uses-permission android:name="com.sonyericsson.home.permission.BROADCAST_BADGE" />
<uses-permission android:name="com.anddoes.launcher.permission.UPDATE_COUNT" />
<uses-permission android:name="com.majeur.launcher.permission.UPDATE_BADGE" />
<uses-feature android:name="android.hardware.bluetooth_le" android:required="false" />
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
<library />
<library />
<uses-feature android:name="android.hardware.wifi" android:required="false" />
<library />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<library />
<application android:allowBackup="false" android:hardwareAccelerated="true" android:icon="@mipmap/icon_v3" android:label="@string/app_name" android:largeHeap="true" android:name="com.snapchat.android.shell.AppShell" android:supportsRtl="false" android:theme="@style/SnapchatTheme">
<provider android:authorities="com.snapchat.android.content.SnapchatProvider" android:exported="false" android:label="@string/snapchat_data" android:name="com.snapchat.android.content.SnapchatProvider">
<grant-uri-permission android:pathPattern=".*" />
</provider>
<provider android:authorities="com.snapchat.android.content.GalleryContentProvider" android:exported="false" android:label="@string/proj1_data" android:name="com.snapchat.android.app.feature.gallery.module.data.database.GalleryContentProvider">
<grant-uri-permission android:pathPattern="*" />
</provider>
<provider android:authorities="com.snapchat.android.fileprovider" android:exported="false" android:grantUriPermissions="true" android:name="com.snapchat.android.app.feature.gallery.module.utils.InternalCacheContentProvider">
<meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/filepaths_for_sharing_protected_content" />
</provider>
<receiver android:exported="true" android:name="com.google.android.gms.gcm.GcmReceiver" android:permission="com.google.android.c2dm.permission.SEND">
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<category android:name="com.snapchat.android" />
</intent-filter>
</receiver>
<meta-data android:name="android.max_aspect" android:value="2.1" />
<receiver android:enabled="true" android:exported="true" android:name="com.snapchat.android.AppInstallBroadcastReceiver">
<intent-filter>
<action android:name="com.android.vending.INSTALL_REFERRER" />
</intent-filter>
</receiver>
<receiver android:enabled="true" android:exported="false" android:name="com.snapchat.android.notification.IgnoreBroadcastReceiver" android:permission="com.google.android.c2dm.permission.SEND">
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<category android:name="com.snapchat.android" />
</intent-filter>
</receiver>
<meta-data android:name="com.google.android.gms.version" android:value="@integer/google_play_services_version" />
<meta-data android:name="com.snapchat.android.app.shared.cameraroll.model.CameraRollGlideModule" android:value="GlideModule" />
<meta-data android:name="com.snapchat.android.framework.glide.ScGlideModule" android:value="GlideModule" />
<meta-data android:name="com.google.android.gms.vision.DEPENDENCIES" android:value="face" />
<activity android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|screenSize|smallestScreenSize|uiMode" android:name="com.google.android.gms.ads.AdActivity" android:theme="@android:style/Theme.Translucent" />
<activity android:launchMode="singleTask" android:name="com.snapchat.android.app.main.deeplink.core.DeepLinkActivity">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="snapchat" />
</intent-filter>
<intent-filter android:autoVerify="true">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="http" />
<data android:scheme="https" />
<data android:host="snapchat.com" />
<data android:host="www.snapchat.com" />
<data android:pathPrefix="/add" />
<data android:pathPrefix="/v" />
<data android:pathPrefix="/discover" />
<data android:pathPrefix="/unlock" />
<data android:pathPrefix="/odg" />
<data android:pathPrefix="/partner" />
<data android:pathPrefix="/search" />
<data android:pathPrefix="/share" />
<data android:pathPattern="/live/..*" />
</intent-filter>
</activity>
<activity android:configChanges="keyboardHidden" android:launchMode="singleTask" android:name="com.snapchat.android.app.main.activity.LoginAndSignupActivity" android:screenOrientation="portrait" android:theme="@style/SnapchatTheme" android:windowSoftInputMode="adjustPan" />
<activity android:configChanges="keyboardHidden|orientation|screenSize" android:launchMode="singleTask" android:name="com.snapchat.android.LandingPageActivity" android:screenOrientation="portrait" android:theme="@style/SnapchatTheme" android:windowSoftInputMode="adjustResize">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<action android:name="android.media.action.STILL_IMAGE_CAMERA" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.SEND" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="image/*" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.SEND" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="text/plain" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.SEND" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="message/rfc822" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.SEND_MULTIPLE" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="image/*" />
</intent-filter>
</activity>
<activity android:configChanges="keyboardHidden" android:name="com.snapchat.android.app.feature.identity.terms.TermsOfUseActivity" android:screenOrientation="portrait" android:windowSoftInputMode="adjustPan|stateHidden" />
<activity android:configChanges="keyboardHidden" android:name="com.snapchat.android.app.feature.support.reporting.InAppReportActivity" android:screenOrientation="portrait" android:windowSoftInputMode="adjustPan|stateHidden" />
<activity android:configChanges="keyboardHidden" android:name="com.snapchat.android.app.feature.tools.shake2report.ShakeToReportActivity" android:screenOrientation="portrait" android:windowSoftInputMode="adjustResize" />
<activity android:configChanges="keyboardHidden" android:name="com.snapchat.android.app.feature.tools.shake2report.ShakeToReportScreenshotEditorActivity" android:screenOrientation="portrait" android:windowSoftInputMode="adjustResize" />
<service android:exported="false" android:name="com.snapchat.android.app.feature.messaging.chat.impl2.SecureChatService" />
<service android:exported="false" android:name="com.snapchat.android.notification.SnapchatGcmListenerService">
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
</intent-filter>
</service>
<service android:exported="false" android:name="com.snapchat.android.service.SnapchatService" />
<service android:exported="false" android:name="com.snapchat.android.framework.network.upload.internal.UploadService" />
<service android:exported="false" android:name="com.snapchat.android.app.core.stickyservice.ScStickyService" />
<service android:exported="false" android:name="com.snapchat.videochat.v2.BackgroundService" />
<service android:exported="false" android:name="com.snapchat.android.talkv3.BackgroundCallService" />
<receiver android:label="@string/widget_title_friend" android:name="com.snapchat.android.widgets.FriendWidget">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
<action android:name="android.intent.action.MY_PACKAGE_REPLACED" />
</intent-filter>
<meta-data android:name="android.appwidget.provider" android:resource="@xml/friend_widget_info" />
</receiver>
<activity android:name="com.snapchat.android.widgets.FriendWidgetConfigureActivity" android:taskAffinity="">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_CONFIGURE" />
</intent-filter>
</activity>
<receiver android:label="@string/widget_title_best_friends" android:name="com.snapchat.android.widgets.BestFriendsWidget">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
<action android:name="android.intent.action.MY_PACKAGE_REPLACED" />
</intent-filter>
<meta-data android:name="android.appwidget.provider" android:resource="@xml/best_friends_widget_info" />
</receiver>
<activity android:name="com.snapchat.android.widgets.BestFriendsWidgetConfigureActivity" android:taskAffinity="">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_CONFIGURE" />
</intent-filter>
</activity>
<service android:exported="false" android:name="com.snapchat.opera.shared.media.exoplayer.ExoMediaPlayerService" android:process=":scplayer" />
<activity android:name="com.braintreepayments.api.AndroidPayActivity" android:theme="@style/bt_transparent_activity" />
<activity android:name="com.braintreepayments.api.threedsecure.ThreeDSecureWebViewActivity" />
<service android:name="com.braintreepayments.api.internal.AnalyticsIntentService" />
<service android:enabled="true" android:name="com.snapchat.laguna.service.LagunaService" />
<receiver android:name="com.snapchat.laguna.service.LagunaWakefulReceiver">
<intent-filter>
<action android:name="snapchat.intent.action.WATCHDOG" />
</intent-filter>
<intent-filter>
<action android:name="snapchat.intent.action.OTA_CHECK" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.BATTERY_OKAY" />
</intent-filter>
<intent-filter>
<action android:name="android.bluetooth.adapter.action.STATE_CHANGED" />
</intent-filter>
<intent-filter>
<action android:name="android.net.wifi.WIFI_STATE_CHANGED" />
</intent-filter>
</receiver>
<activity android:name="com.google.android.gms.ads.purchase.InAppPurchaseActivity" android:theme="@style/Theme.IAPTheme" />
<activity android:name="com.brightcove.player.captioning.BrightcoveCaptionPropertiesActivity" />
<service android:exported="false" android:name="com.mapbox.services.android.telemetry.service.TelemetryService" />
<activity android:name="net.hockeyapp.android.UpdateActivity" />
<activity android:name="net.hockeyapp.android.FeedbackActivity" />
<activity android:name="net.hockeyapp.android.PaintActivity" />
<activity android:name="net.hockeyapp.android.LoginActivity" />
<activity android:name="net.hockeyapp.android.ExpiryInfoActivity" />
</application>
</manifest>
Can someone show me the correct way of doing this?
The closest I got to success, is opening an URL with Instagram like so:
adb shell am start -a android.intent.action.VIEW -d %s com.instagram.android
And adding a user through Snapchat like so:
adb shell am start -a android.intent.action.VIEW -d "http://snapchat.com/add/something" com.snapchat.android
EDIT:
To clarify and simplify, after some research I have found the java code to share media with Snapchat:
Intent sharingIntent = new Intent(Intent.ACTION_SEND);
sharingIntent.setType("image/jpg");
sharingIntent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
File newFile = new File(getContext().getCacheDir(), "share_score.jpg");
Log.d(getClass().getSimpleName(), newFile.getAbsolutePath());
Uri image = FileProvider.getUriForFile(getContext(), "com.test.fileprovider", newFile);
try {
// create bitmap screen capture
View v1 = v.getRootView();
v1.setDrawingCacheEnabled(true);
Bitmap bitmap = Bitmap.createBitmap(v1.getDrawingCache());
v1.setDrawingCacheEnabled(false);
FileOutputStream outputStream = new FileOutputStream(newFile);
int quality = 100;
bitmap.compress(Bitmap.CompressFormat.JPEG, quality, outputStream);
outputStream.flush();
outputStream.close();
} catch (Throwable e) {
// Several error may come out with file handling or OOM
e.printStackTrace();
}
sharingIntent.putExtra(Intent.EXTRA_STREAM, image);
startActivity(Intent.createChooser(sharingIntent, getString(R.string.share_via)));
(From here)
But I want to figure out how to do this using adb and activity manager only, so I can make an extension for windows to share from PC to Snapchat on mobile.
It seems the java snippet is using Intent.EXTRA_STREAM
however, I don't know what the equivalent is when using the activity manager from the command line.
EDIT 2:
As suggested by @war_Hero, I tried:
adb shell am start -t image/* -d file:///mnt/sdcard/_tmp/1.jpg
This shows a 'open with' dialog, and while I can open the image fine with the android gallery, both Snapchat and Instagram crash when selecting them.
Other apps like Twitter and Telegram don't open the image and just launch the main activity.
EDIT 3:
As suggested I tried adb shell am start -d file:///mnt/sdcard/_tmp/1.jpg -t image/jpg -a android.intent.action.VIEW
This is a valid command, however not compatible with Snapchat, Snapchat only takes the SEND
action, see here:
<intent-filter>
<action android:name="android.intent.action.SEND" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="image/*" />
</intent-filter>
The following command does work with snapchat, however it fails to load / display the image:
adb shell am start -a android.intent.action.SEND -t "image/*" -d "file:///mnt/sdcard/_tmp/1.jpg" com.snapchat.android
To make sure this is not a permission issue, we can add the flag:
--grant-read-uri-permission
(see here)
However, unfortunately this results in the same result.
The snapchat app loads, opens but fails to display the image.
From the originally posted java snippet, you can see that the intent set is EXTRA_STREAM
.
I think that I am sending it different by using -d file:///...
, I would probably need to figure out what the commandline command is for EXTRA_STREAM
instead.
EDIT 4:
After some fiddling, I created a working java snippet.
File dir = Environment.getExternalStorageDirectory();
File yourFile = new File(dir, "/_tmp/1.jpg");
Uri yourFileUri = Uri.fromFile(yourFile);
Intent sendIntent = new Intent();
sendIntent.setAction(Intent.ACTION_SEND);
sendIntent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
sendIntent.setType("image/*");
sendIntent.putExtra(Intent.EXTRA_STREAM, yourFileUri);
sendIntent.setPackage("com.snapchat.android");
startActivity(sendIntent);
Now what I need to know, is how to execute that snippet from the commandline.