I made an app using Parse as backend. I am able to get the notification but when i tap on it, the app crashes.
Here are the java and XML files.
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="chipset.lugmnotifier">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<permission
android:name="chipset.lugmnotifier.permission.C2D_MESSAGE"
android:protectionLevel="signature" />
<uses-permission android:name="chipset.lugmnotifier.permission.C2D_MESSAGE" />
<application
android:name=".resources.ParseInitApplication"
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme">
<meta-data
android:name="com.parse.push.notification_icon"
android:resource="#drawable/ic_notification" />
<activity
android:name=".HomeActivity"
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=".AdminActivity"
android:label="#string/title_activity_admin"
android:parentActivityName=".HomeActivity">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".HomeActivity" />
</activity>
<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.parse.ParsePushBroadcastReceiver"
android:exported="false">
<intent-filter>
<action android:name="com.parse.push.intent.RECEIVE" />
<action android:name="com.parse.push.intent.DELETE" />
<action android:name="com.parse.push.intent.OPEN" />
</intent-filter>
</receiver>
<receiver
android:name="com.parse.GcmBroadcastReceiver"
android:permission="com.google.android.c2dm.permission.SEND">
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<action android:name="com.google.android.c2dm.intent.REGISTRATION" />
<category android:name="chipset.lugmnotifier" />
</intent-filter>
</receiver>
</application>
</manifest>
ParseInitApplication.java
import android.app.Application;
import android.util.Log;
import com.parse.Parse;
import com.parse.ParseException;
import com.parse.ParseInstallation;
import com.parse.ParsePush;
import com.parse.SaveCallback;
import static chipset.lugmnotifier.resources.Constants.APPLICATION_ID;
import static chipset.lugmnotifier.resources.Constants.CLIENT_KEY;
public class ParseInitApplication extends Application {
#Override
public void onCreate() {
super.onCreate();
Parse.initialize(this, APPLICATION_ID, CLIENT_KEY);
ParsePush.subscribeInBackground("", new SaveCallback() {
#Override
public void done(ParseException e) {
if (e != null) {
Log.d("com.parse.push", "successfully subscribed to the broadcast channel.");
} else {
Log.e("com.parse.push", "failed to subscribe for push", e);
}
}
});
ParseInstallation.getCurrentInstallation().saveInBackground();
}
}
HomeActivity.java
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.text.method.PasswordTransformationMethod;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.EditText;
import android.widget.ListView;
import com.parse.FindCallback;
import com.parse.ParseAnalytics;
import com.parse.ParseException;
import com.parse.ParseObject;
import com.parse.ParseQuery;
import org.duncavage.swipetorefresh.widget.SwipeRefreshLayout;
import java.util.List;
import chipset.lugmnotifier.resources.Functions;
import chipset.lugmnotifier.resources.NotificationListViewAdapter;
import de.keyboardsurfer.android.widget.crouton.Crouton;
import de.keyboardsurfer.android.widget.crouton.Style;
import static chipset.lugmnotifier.resources.Constants.KEY_CLASS_NOTIFICATION;
import static chipset.lugmnotifier.resources.Constants.KEY_DETAIL;
import static chipset.lugmnotifier.resources.Constants.KEY_TITLE;
import static chipset.lugmnotifier.resources.Constants.PASSWORD;
public class HomeActivity extends Activity {
ListView notificationsListView;
SwipeRefreshLayout notificationSwipeRefreshLayout;
Functions functions = new Functions();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home);
ParseAnalytics.trackAppOpened(getIntent());
notificationSwipeRefreshLayout = (SwipeRefreshLayout) findViewById(R.id.notificationSwipeRefreshLayout);
notificationsListView = (ListView) findViewById(R.id.notificationListView);
notificationSwipeRefreshLayout.setColorScheme(R.color.alizarin, R.color.emerald, R.color.peterRiver, R.color.sunFlower);
notificationSwipeRefreshLayout.setActionBarSwipeIndicatorText(R.string.swipe_to_refresh);
notificationSwipeRefreshLayout.setActionBarSwipeIndicatorRefreshingText(R.string.loading);
notificationSwipeRefreshLayout.setActionBarSwipeIndicatorBackgroundColor(
getResources().getColor(R.color.alizarin));
notificationSwipeRefreshLayout.setActionBarSwipeIndicatorTextColor(
getResources().getColor(R.color.clouds));
notificationSwipeRefreshLayout.setActionBarSwipeIndicatorRefreshingTextColor(
getResources().getColor(R.color.clouds));
notificationSwipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
#Override
public void onRefresh() {
new FetchData().getNotifications();
}
});
new FetchData().getNotifications();
}
private class FetchData {
public void getNotifications() {
if (functions.isConnected(getApplicationContext())) {
notificationSwipeRefreshLayout.setRefreshing(true);
ParseQuery<ParseObject> query = ParseQuery.getQuery(KEY_CLASS_NOTIFICATION);
query.findInBackground(new FindCallback<ParseObject>() {
#Override
public void done(List<ParseObject> parseObjects, ParseException e) {
notificationSwipeRefreshLayout.setRefreshing(false);
final String[] title = new String[parseObjects.size()];
final String[] detail = new String[parseObjects.size()];
if (e == null) {
for (int i = 0; i < parseObjects.size(); i++) {
title[i] = parseObjects.get(i).getString(KEY_TITLE);
detail[i] = parseObjects.get(i).getString(KEY_DETAIL);
}
notificationsListView.setAdapter(new NotificationListViewAdapter(getApplicationContext(), title, detail));
notificationsListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
Crouton.showText(HomeActivity.this, title[i] + " - " + detail[i], Style.INFO);
}
});
} else {
Crouton.showText(HomeActivity.this, e.getMessage(), Style.ALERT);
}
}
});
} else {
notificationSwipeRefreshLayout.setRefreshing(false);
Crouton.showText(HomeActivity.this, "No internet connection", Style.ALERT);
}
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_admin) {
final EditText passwordEditText = new EditText(HomeActivity.this);
passwordEditText.setTransformationMethod(PasswordTransformationMethod.getInstance());
AlertDialog.Builder builder = new AlertDialog.Builder(HomeActivity.this);
builder.setTitle("Admin Panel");
builder.setMessage("Enter the admin password");
builder.setView(passwordEditText);
builder.setPositiveButton("LOGIN", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
if (passwordEditText.getText().toString().equals(PASSWORD)) {
startActivity(new Intent(HomeActivity.this, AdminActivity.class));
} else {
Crouton.showText(HomeActivity.this, "Incorrect Password", Style.ALERT);
}
}
});
builder.setNeutralButton("CANCEL", null);
builder.create();
builder.show();
}
return super.onOptionsItemSelected(item);
}
}
StackTrace (of the crash)
10:46:02.302 15739-15739/chipset.lugmnotifier E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: chipset.lugmnotifier, PID: 15739
java.lang.RuntimeException: Unable to start receiver com.parse.ParsePushBroadcastReceiver: android.content.ActivityNotFoundException: No Activity found to handle Intent { act=android.intent.action.VIEW dat= flg=0x1000c000 (has extras) }
at android.app.ActivityThread.handleReceiver(ActivityThread.java:2414)
at android.app.ActivityThread.access$1700(ActivityThread.java:135)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1272)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5001)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)
at dalvik.system.NativeStart.main(Native Method)
Caused by: android.content.ActivityNotFoundException: No Activity found to handle Intent { act=android.intent.action.VIEW dat= flg=0x1000c000 (has extras) }
at android.app.Instrumentation.checkStartActivityResult(Instrumentation.java:1632)
at android.app.Instrumentation.execStartActivitiesAsUser(Instrumentation.java:1481)
at android.app.ContextImpl.startActivitiesAsUser(ContextImpl.java:1080)
at android.content.ContextWrapper.startActivitiesAsUser(ContextWrapper.java:344)
at android.content.ContextWrapper.startActivitiesAsUser(ContextWrapper.java:344)
at android.app.TaskStackBuilder.startActivities(TaskStackBuilder.java:221)
at android.app.TaskStackBuilder.startActivities(TaskStackBuilder.java:232)
at android.app.TaskStackBuilder.startActivities(TaskStackBuilder.java:208)
at com.parse.TaskStackBuilderHelper.startActivities(TaskStackBuilderHelper.java:19)
at com.parse.ParsePushBroadcastReceiver.onPushOpen(ParsePushBroadcastReceiver.java:202)
at com.parse.ParsePushBroadcastReceiver.onReceive(ParsePushBroadcastReceiver.java:108)
at android.app.ActivityThread.handleReceiver(ActivityThread.java:2407)
at android.app.ActivityThread.access$1700(ActivityThread.java:135)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1272)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5001)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)
at dalvik.system.NativeStart.main(Native Method)
I want to open HomeActivity on notification tap. Any help will be appreciated. If any other file is required, please let me know I'll add it.
Quoting from below post by Ahmad Raza
Exception when opening Parse push notification
You can extend ParsePushBroadcastReceiver and override onPushOpen method.
public class Receiver extends ParsePushBroadcastReceiver {
#Override
public void onPushOpen(Context context, Intent intent) {
Log.e("Push", "Clicked");
Intent i = new Intent(context, HomeActivity.class);
i.putExtras(intent.getExtras());
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(i);
}
}
Use it in manifest, (Instead of using ParsePushBroadcastReceiver)
<receiver
android:name="your.package.name.Receiver"
android:exported="false" >
<intent-filter>
<action android:name="com.parse.push.intent.RECEIVE" />
<action android:name="com.parse.push.intent.DELETE" />
<action android:name="com.parse.push.intent.OPEN" />
</intent-filter>
</receiver>
After a long effort, it worked for me:
ParsePushApplication.java
public class ParsePushApplication extends Application {
#Override
public void onCreate(){
super.onCreate();
Parse.initialize(this, "App_Key", "Client_Key");
ParseInstallation.getCurrentInstallation().saveInBackground();
}
}
MainActivity.java
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ParseAnalytics.trackAppOpenedInBackground(getIntent());
try {
Intent intent = getIntent();
Bundle extras = intent.getExtras();
if (extras != null) {
String jsonData = extras.getString("com.parse.Data");
JSONObject json;
json = new JSONObject(jsonData);
String pushStore = json.getString("alert");
Toast.makeText(MainActivity.this, pushStore, Toast.LENGTH_LONG).show();
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Receiver.java
public class Receiver extends ParsePushBroadcastReceiver {
private static final String TAG = "MyNotificationsReceiver";
#Override
public void onPushOpen(Context context, Intent intent) {
Log.e("Push", "Clicked");
Intent i = new Intent(context, MainActivity.class);
i.putExtras(intent.getExtras());
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(i);
}
}
Manifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="your.package.name">
<!-- IMPORTANT: Change "your.package.name" to match your app's package name. -->
<application
android:name=".ParsePushApplication"
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<meta-data
android:name="com.parse.push.notification_icon"
android:resource="#drawable/push_icon"/>
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<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="your.package.name.Receiver"
android:exported="false" >
<intent-filter>
<action android:name="com.parse.push.intent.RECEIVE" />
<action android:name="com.parse.push.intent.DELETE" />
<action android:name="com.parse.push.intent.OPEN" />
</intent-filter>
</receiver>
<receiver android:name="com.parse.GcmBroadcastReceiver"
android:permission="com.google.android.c2dm.permission.SEND">
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<action android:name="com.google.android.c2dm.intent.REGISTRATION" />
<!--
IMPORTANT: Change "your.package.name" to match your app's package name.
-->
<category android:name="your.package.name" />
</intent-filter>
</receiver>
</application>
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<!--
IMPORTANT: Change "your.package.name.permission.C2D_MESSAGE" in the lines below
to match your app's package name + ".permission.C2D_MESSAGE".
-->
<permission android:protectionLevel="signature"
android:name="your.package.name.permission.C2D_MESSAGE" />
<uses-permission android:name="com.zeeroapps.parsetutorial_cli.permission.C2D_MESSAGE" />
</manifest>
Related
I am trying to implement screen pinning on an Android 5.1 Device. I came across This Answer, and in trying to add a intent-filter to my Manifest, I get this error: Cannot resolve symbol '#xml/device_admin'.
I assume this is because xml/device_admin doesn't exist, so if this is the case, where do I create it?
My Manifest
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="MY_PACKAGE">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<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=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<action android:name="android.app.action.PROFILE_PROVISIONING_COMPLETE" />
</intent-filter>
</activity>
<receiver
android:name=".MyDeviceAdminReceiver"
android:label="#string/app_name"
android:permission="android.permission.BIND_DEVICE_ADMIN">
<meta-data
android:name="android.app.device_admin"
android:resource="#xml/device_admin" />
<intent-filter>
<action android:name="android.app.action.DEVICE_ADMIN_ENABLED" />
</intent-filter>
</receiver>
<!-- <receiver android:name=".BootReceiver"> -->
<!-- <intent-filter > -->
<!-- <action android:name="android.intent.action.BOOT_COMPLETED"/> -->
<!-- </intent-filter> -->
<!-- </receiver> -->
</application>
</manifest>
My MainActivity
package MY_PACKAGE;
import android.content.ComponentName;
import android.content.Context;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.KeyEvent;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.app.admin.*;
public class MainActivity extends AppCompatActivity {
private WebView mWebView;
private static final String TAG = "MainActivity";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ComponentName deviceAdmin = new ComponentName(this, MyDeviceAdminReceiver.class);
DevicePolicyManager mDpm = (DevicePolicyManager) getSystemService(Context.DEVICE_POLICY_SERVICE);
mWebView = (WebView) findViewById(R.id.activity_main_webview);
// Enable Javascript
WebSettings webSettings = mWebView.getSettings();
webSettings.setJavaScriptEnabled(true);
mWebView.setWebViewClient(new WebViewClient());
mWebView.loadUrl("my_website.com"); //Note that this is a placeholder website.
if (mDpm.isDeviceOwnerApp(getPackageName())) {
mDpm.setLockTaskPackages(deviceAdmin, new String[]{getPackageName()});
}
if (mDpm.isLockTaskPermitted(this.getPackageName()))
startLockTask();
// try {
// Runtime.getRuntime().exec("dpm set-device-owner MY_PACKAGE/.MyDeviceAdminReceiver");
// } catch (Exception e) {
// Log.e(TAG, "device owner not set");
// Log.e(TAG, e.toString());
// e.printStackTrace();
// }
try {
startLockTask();
} catch (Exception e) {
e.printStackTrace();
}
}
#Override
public void onBackPressed() {
if(mWebView.canGoBack()) {
mWebView.goBack();
} else {
System.out.print("LOCKED IN PLACE!");
}
}
}
I assume this is because xml/device_admin doesn't exist, so if this is
the case, where do I create it?
Create Folder in hierarchy application/src/main/res/xml keep the file device_admin.xml in this XML folder
Structure of device_admin.xml file is
<device-admin xmlns:android="http://schemas.android.com/apk/res/android">
<uses-policies>
<limit-password />
<watch-login />
<reset-password />
<force-lock />
<wipe-data />
<expire-password />
<encrypted-storage />
<disable-camera />
</uses-policies>
</device-admin>
Device_admin GuideLine
I'm developing this android application, that receives data from the gallery (in my case an image) and displays it. What i also had to do is to create a SplashScreen for my app. But when i did my intent became null .
Manifest code:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.xkbc1923.myapplication">
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<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=".SplashScreen">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".AlertExampleActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.SEND" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="image/*" />
<data android:mimeType="text/*" />
</intent-filter>
</activity>
</application>
SplashScreen
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
public class SplashScreen extends Activity {
private static final int DISPLAY_DURATION = 1000;
#Override
protected final void onCreate(final Bundle savedInstState) {
super.onCreate(savedInstState);
setContentView(R.layout.activity_splashscreen);
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
Intent i = new Intent(SplashScreen.this, AlertExampleActivity.class);
startActivity(i);
// close this activity
finish();
}
}, DISPLAY_DURATION);
}
}
MainActivity
import android.app.Dialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.net.Uri;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import java.io.File;
import static android.provider.CalendarContract.CalendarCache.URI;
public class AlertExampleActivity extends AppCompatActivity {
ImageView picView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
///get the image view
//get the text view
setContentView(R.layout.activity_alert_example);
picView = (ImageView) findViewById(R.id.picture);
TextView txtView = (TextView) findViewById(R.id.txt);
if (txtView ==null) {
Log.w("Example", "TextView is null");
}
//get the received intent
Intent receivedIntent = getIntent();
//get the action
String receivedAction = receivedIntent.getAction();
//find out what we are dealing with
String receivedType = receivedIntent.getType();
//make sure it's an action and type we can handle
if (receivedAction.equals(Intent.ACTION_SEND)) {
Log.d("Example", "Send received");
//content is being shared
if (receivedType.startsWith("text/")) {
Log.d("Example", "Text received");
//handle sent text
//hide the other ui item
picView.setVisibility(View.GONE);
//get the received text
String receivedText = receivedIntent.getStringExtra(Intent.EXTRA_TEXT);
//check we have a string
if (receivedText != null) {
//set the text
txtView.setText(receivedText);
}
} else if (receivedType.startsWith("image/")) {
Log.d("Example", "Image received");
//handle sent image
handleSendImage(receivedIntent);
}
} else if (receivedAction.equals(Intent.ACTION_MAIN)) {
//app has been launched directly, not from share list
Log.d("Example", "Direct launch of App");
}
}
private void handleSendImage(Intent intent) {
// Get the image URI from intent
Uri imageUri = (Uri) intent.getParcelableExtra(Intent.EXTRA_STREAM);
// When image URI is not null
if (imageUri != null) {
// Update UI to reflect image being shared
picView.setImageURI(imageUri);
} else{
Toast.makeText(this, "Error occured, URI is invalid", Toast.LENGTH_LONG).show();
}
}
}
You did not add any extra data to your intent. So it would be null normally. Just add necessary data to Intent (i) on SplashScreen.java. Ex -
i.setAction("action");
i.setType("type");
i.putExtra("key", "value");
I am not sure if this gonna solve your problem but you can try.
Instead of :
Intent i = new Intent(SplashScreen.this, AlertExampleActivity.class);
startActivity(i);
// close this activity
finish();
Try this:
startActivity(new Intent(SplashScreen.this, AlertExampleActivity.class));
finish();
I've changed the manifest file since i want the splashscreen to appear even when it's externally called .
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<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=".AlertExampleActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
<activity android:name=".SplashScreen">
<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.SEND" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="image/*" />
<data android:mimeType="text/*" />
</intent-filter>
</activity>
</application>
And changed the SplashscreenActivity :
public class SplashScreen extends Activity {
private static final int DISPLAY_DURATION = 1000;
#Override
protected final void onCreate(final Bundle savedInstState) {
super.onCreate(savedInstState);
setContentView(R.layout.activity_splashscreen);
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
Intent i = new Intent(SplashScreen.this, AlertExampleActivity.class);
i.setAction(Intent.ACTION_SEND);
i.setType("*/*");
String[] mimetypes = {"image/*", "video/*"};
i.putExtra(Intent.EXTRA_MIME_TYPES, mimetypes);
startActivity(i);
// close this activity
finish();
}
}, DISPLAY_DURATION);
}
}
I haven't changed anything in the MainActivity , but now i no longer receive the image ... I'm new to Android so i would really appreciate the explanation.
I build an android app composed by a web view, in parse.com i've got my device registered but when i send a push notification in "pushes sent" there is 0 pushes.
this is my Mainactivity:
import com.party.bparty.MainActivity;
import com.parse.Parse;
import com.parse.ParseInstallation;
import com.parse.ParsePush;
import com.parse.ParseQuery;
import com.parse.PushService;
public class MainActivity extends ActionBarActivity {
private WebView mWebView;
private String url = "http://www.bestparty.altervista.org";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//attivo parse per le notifiche
Parse.initialize(this,"zJxpd9798Ns6A9rzUDpe78ElRY0I99ES3LD6nDQV","kmAmA1iTbC32BTE9ERtzNOoHXbJchhIn6tyPXKMi");
PushService.setDefaultPushCallback(this, MainActivity.class);
ParseInstallation.getCurrentInstallation().saveInBackground();
//...
//...initializing and loading the contentview and the webview
}
//options menu omitted
}
this is my MycustomReceiver
public class MyCustomReceiver extends BroadcastReceiver {
private static final String TAG = "MyCustomReceiver";
#Override
public void onReceive(Context context, Intent intent) {
try {
if (intent == null)
Log.d(TAG, "Receiver intent null");
else {
String action = intent.getAction();
Log.d(TAG, "got action " + action );
if (action.equals("com.party.bparty.UPDATE_STATUS")) {
String channel = intent.getExtras().getString("com.parse.Channel");
JSONObject json = new JSONObject(intent.getExtras().getString("com.parse.Data"));
Log.d(TAG, "got action " + action + " on channel " + channel + " with:");
Iterator itr = json.keys();
while (itr.hasNext()) {
String key = (String) itr.next();
if (key.equals("customdata")) {
Intent pupInt = new Intent(context, ShowPopUp.class);
pupInt.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK );
context.getApplicationContext().startActivity(pupInt);
}
Log.d(TAG, "..." + key + " => " + json.getString(key));
}
}
}
}
catch (JSONException e) {
Log.d(TAG, "JSONException: " + e.getMessage());
}
}
}
and this is my ShowPopup
public class ShowPopUp extends Activity implements OnClickListener {
Button ok, cancel;
boolean click = true;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setTitle("Cupon");
setContentView(R.layout.popupdialog);
ok = (Button)findViewById(R.id.popOkB);
ok.setOnClickListener(this);
cancel = (Button)findViewById(R.id.popCancelB);
cancel.setOnClickListener(this);
}
#Override
public void onClick(View arg0) {
finish();
}
}
And this is my manifest
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.party.bparty"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="21" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<permission
android:name="com.androidhive.pushnotifications.permission.C2D_MESSAGE"
android:protectionLevel="signature" />
<uses-permission android:name="com.androidhive.pushnotifications.permission.C2D_MESSAGE" />
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.VIBRATE" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name=".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>
<activity
android:name="com.party.bparty.ShowPopUp"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
</activity>
<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.RECEIVE_BOOT_COMPLETED" />
<action android:name="android.intent.action.USER_PRESENT" />
</intent-filter>
</receiver>
<receiver android:name="com.party.bparty.MyCustomReceiver" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.intent.action.USER_PRESENT" />
<action android:name="com.iakremera.pushnotificationdemo.UPDATE_STATUS" />
</intent-filter>
</receiver>
</application>
</manifest>
Where's my error?
I do it, but it doesn't work anyway
" if (action.equals("com.party.bparty.UPDATE_STATUS")) {
Pick one, either com.party.bparty.UPDATE_STATUS or com.iakremera.pushnotificationdemo.UPDATE_STATUS"
but Now i have 1 "PUSH SENT" in push sent, but my device doesn't show any push
Your receiver has the wrong filter. Your receiver is declared as this:
<receiver android:name="com.party.bparty.MyCustomReceiver" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.intent.action.USER_PRESENT" />
<action android:name="com.iakremera.pushnotificationdemo.UPDATE_STATUS" />
</intent-filter>
</receiver>
but you are checking for a different intent action in the code:
if (action.equals("com.party.bparty.UPDATE_STATUS")) {
Pick one, either com.party.bparty.UPDATE_STATUS or com.iakremera.pushnotificationdemo.UPDATE_STATUS and also make sure that Parse knows which one it is when you perform the push itself.
this is the sender code which is used to send message to gcm.
//sJSONObject obj = new JSONObject();
Sender sender = new Sender(GOOGLE_SERVER_KEY);
Message message = new Message.Builder().timeToLive(120)
.delayWhileIdle(true).addData(MESSAGE_KEY, userMessage).build();
System.out.println("regId: " + regId);
Object result = sender.send(message, regId, 5);
if (StringUtils.isEmpty(((Result) result).getErrorCodeName())) {
System.out.println("success");
System.out.println(result.toString());
}
else{
System.out.println(((Result) result).getErrorCodeName());
System.out.println(result.toString());
}
Manifest file:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<permission
android:name="com.javapapers.android.permission.C2D_MESSAGE"
android:protectionLevel="signature" />
<uses-permission android:name="com.javapapers.android.permission.C2D_MESSAGE" />
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-sdk
android:minSdkVersion="9"
android:targetSdkVersion="15" />
<application
android:icon="#drawable/ic_launcher"
android:label="#string/app_name" >
<activity
android:name=".RegisterActivity"
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="com.javapapers.android.MainActivity"
android:configChanges="orientation|keyboardHidden"
android:label="#string/app_name" >
</activity>
<receiver
android:name=".GcmBroadcastReceiver"
android:permission="com.google.android.c2dm.permission.SEND" >
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<action android:name="com.google.android.c2dm.intent.REGISTRATION" />
<category android:name="com.javapapers.android" />
</intent-filter>
</receiver>
<service android:name=".GCMNotificationIntentService" />
<!-- added by shashank -->
<meta-data android:name="com.google.android.gms.version"
android:value="#integer/google_play_services_version" />
</application>
CCMBroadcastreciever:
package com.javapapers.android;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.support.v4.content.WakefulBroadcastReceiver;
import android.util.Log;
public class GcmBroadcastReceiver extends WakefulBroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Log.d("GCMBroadcastReceiver", "OnReceive method");
System.out.println( "Broadcast receiver OnReceive method");
ComponentName comp = new ComponentName(context.getPackageName(),
GCMNotificationIntentService.class.getName());
startWakefulService(context, (intent.setComponent(comp)));
setResultCode(Activity.RESULT_OK);
}
}
GCMNotificationIntentService:
package com.javapapers.android;
import android.app.IntentService;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.SystemClock;
import android.support.v4.app.NotificationCompat;
import android.util.Log;
import com.google.android.gms.gcm.GoogleCloudMessaging;
public class GCMNotificationIntentService extends IntentService {
public static final int NOTIFICATION_ID = 1;
private NotificationManager mNotificationManager;
NotificationCompat.Builder builder;
public GCMNotificationIntentService() {
super("GcmIntentService");
}
public static final String TAG = "GCMNotificationIntentService";
#Override
protected void onHandleIntent(Intent intent) {
Log.d("GCMNotificationIntentService", "OnHandleIntent method");
System.out.println( "GCMNotificationIntentService OnHandleIntent method");
Bundle extras = intent.getExtras();
GoogleCloudMessaging gcm = GoogleCloudMessaging.getInstance(this);
String messageType = gcm.getMessageType(intent);
if (!extras.isEmpty()) {
if (GoogleCloudMessaging.MESSAGE_TYPE_SEND_ERROR
.equals(messageType)) {
sendNotification("Send error: " + extras.toString());
} else if (GoogleCloudMessaging.MESSAGE_TYPE_DELETED
.equals(messageType)) {
sendNotification("Deleted messages on server: "
+ extras.toString());
} else if (GoogleCloudMessaging.MESSAGE_TYPE_MESSAGE
.equals(messageType)) {
for (int i = 0; i < 3; i++) {
Log.i(TAG,
"Working... " + (i + 1) + "/5 # "
+ SystemClock.elapsedRealtime());
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
}
}
Log.i(TAG, "Completed work # " + SystemClock.elapsedRealtime());
sendNotification("Message Received from Google GCM Server: "
+ extras.get(Config.MESSAGE_KEY));
Log.i(TAG, "Received: " + extras.toString());
}
}
GcmBroadcastReceiver.completeWakefulIntent(intent);
}
private void sendNotification(String msg) {
Log.d(TAG, "Preparing to send notification...: " + msg);
mNotificationManager = (NotificationManager) this
.getSystemService(Context.NOTIFICATION_SERVICE);
PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
new Intent(this, MainActivity.class), 0);
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(
this).setSmallIcon(R.drawable.gcm_cloud)
.setContentTitle("GCM Notification")
.setStyle(new NotificationCompat.BigTextStyle().bigText(msg))
.setContentText(msg);
mBuilder.setContentIntent(contentIntent);
mNotificationManager.notify(NOTIFICATION_ID, mBuilder.build());
Log.d(TAG, "Notification sent successfully.");
}
}
Output:
success
[ messageId=0:1414564158966354%31e4cc17f9fd7ecd ]
Still i'm not getting push notification on emulator. i have tried it on device as well. same problem occurs there as well.
I had a similar problem. I solved it using the classes in This GitHub example specifically noting the following:
Three 'services' and one 'receiver' together with all the permissions added in the github example.
AndroidManifest.xml
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.READ_PROFILE" />
<uses-permission android:name="android.permission.READ_CONTACTS" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<uses-permission android:name="android.permission.VIBRATE" />
<permission
android:name="<yourpackagename>.permission.C2D_MESSAGE"
android:protectionLevel="signature" />
<uses-permission android:name="<yourpackagename>.permission.C2D_MESSAGE" />
<service
android:name=".utility.MyGcmRegistrationIntentService"
android:exported="false" >
</service>
<service
android:name=".utility.MyGcmListenerService"
android:exported="false" >
<intent-filter>
actionandroid:name="com.google.android.c2dm.intent.RECEIVE" />
</intent-filter</service>
<service
android:name=".utility.MyInstanceIdListenerService"
android:exported="false">
<intent-filter>
<action android:name="com.google.android.gms.iid.InstanceID"/>
</intent-filter>
</service>
<receiver
android:name="com.google.android.gms.gcm.GcmReceiver"
android:exported="true"
android:permission="com.google.android.c2dm.permission.SEND" >
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<action android:name="com.google.android.c2dm.intent.REGISTRATION"/>
<category android:name="<com.example.yourpackagename>" />
</intent-filter>
</receiver>
The Receiver is implemented in the
ActivityMain.java:
mRegistrationBroadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context);
boolean sentToken = sharedPreferences.getBoolean(SENT_TOKEN_TO_SERVER, false);
if (sentToken) {
} else {
}
}
};
#Override
protected void onResume() {
super.onResume();
LocalBroadcastManager.getInstance(this).registerReceiver(mRegistrationBroadcastReceiver,
new IntentFilter("registrationComplete"));
}
#Override
protected void onPause() {
LocalBroadcastManager.getInstance(this).unregisterReceiver(mRegistrationBroadcastReceiver);
super.onPause();
}
You can basically use the other files just like they are:
MyGcmListenerService.java - The one where you can customize your notification icon and text.
MyInstanceIDListenerService.java
QuickstartPreferences.java
RegistrationIntentService.java
Okay so I've been messing around with the Twitter API, and all of a sudden I've started to get the ClassNotFoundException error code when I try and enter the Activity which has my login box to sign into Twitter.
Here's the error code.
2398-2398/josh.com.twitterapi E/dalvikvm﹕ Could not find class 'josh.com.twitterapi.LoginActivity', referenced from method josh.com.twitterapi.NavigationDrawerFragment.selectItem
07-05 02:19:30.138 2398-2398/josh.com.twitterapi E/AndroidRuntime﹕ FATAL EXCEPTION: main
java.lang.NoClassDefFoundError: josh.com.twitterapi.LoginActivity
at josh.com.twitterapi.NavigationDrawerFragment.selectItem(NavigationDrawerFragment.java:204)
at josh.com.twitterapi.NavigationDrawerFragment.access$000(NavigationDrawerFragment.java:32)
at josh.com.twitterapi.NavigationDrawerFragment$1.onItemClick(NavigationDrawerFragment.java:99)
at android.widget.AdapterView.performItemClick(AdapterView.java:301)
at android.widget.AbsListView.performItemClick(AbsListView.java:1280)
at android.widget.AbsListView$PerformClick.run(AbsListView.java:3071)
at android.widget.AbsListView$1.run(AbsListView.java:3973)
at android.os.Handler.handleCallback(Handler.java:615)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4867)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1007)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:774)
at dalvik.system.NativeStart.main(Native Method)
07-05 02:21:03.973 3223-3223/josh.com.twitterapi E/dalvikvm﹕ Could not find class 'josh.com.twitterapi.LoginActivity', referenced from method josh.com.twitterapi.NavigationDrawerFragment.selectItem
This is my LoginActivity.java.
package josh.com.socialme;
import android.os.Bundle;
import android.view.Menu;
import android.view.View;
import com.codepath.oauth.OAuthLoginActivity;
public class LoginActivity extends OAuthLoginActivity<TwitterClient> {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
}
// Inflate the menu; this adds items to the action bar if it is present.
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.login, menu);
return true;
}
// OAuth authenticated successfully, launch primary authenticated activity
// i.e Display application "homepage"
#Override
public void onLoginSuccess() {
// Intent i = new Intent(this, PhotosActivity.class);
// startActivity(i);
}
// OAuth authentication flow failed, handle the error
// i.e Display an error dialog or toast
#Override
public void onLoginFailure(Exception e) {
e.printStackTrace();
}
// Click handler method for the button used to start OAuth flow
// Uses the client to initiate OAuth authorization
// This should be tied to a button used to login
public void loginToRest(View view) {
getClient().connect();
}
}
This is my AndroidManifest.
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="josh.com.socialme" >
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/Theme.AppCompat.Light.DarkActionBar" >
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<activity
android:name=".Hub"
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=".Feed"
android:label="#string/title_activity_feed" >
</activity>
<activity
android:name=".LoginActivity"
android:label="#string/app_name" >
</activity>
</application>
</manifest>
And this is my method I use to get to the activity.
private void selectItem(int position) {
// Handle Navigation Options
Intent intent;
switch (position) {
case 1:
intent = new Intent(getActivity(), Feed.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
getActivity().startActivity(intent);
break;
case 2:
intent = new Intent(getActivity(), LoginActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
getActivity().startActivity(intent);
break;
}
}
I would greatly appreciate it if someone could point me towards the right direction.
Kind regards,
Josh
(AndroidManifest.xml as requested)
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="josh.com.socialme" >
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/Theme.AppCompat.Light.DarkActionBar" >
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<activity
android:name=".Hub"
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=".Feed"
android:label="#string/title_activity_feed" >
</activity>
<activity
android:name=".LoginActivity"
android:label="#string/title_login_activity" >
</activity>
</application>
</manifest>