I have build a widget with an imageview. I want when the user clicks on the imageview, an activity will be started. That activity gets extras from the intent(strings, ints). It almost works, but when the widget updates, the old extras are get, not the new ones, given in the AppWidgetProvider. How can I solve this problem?
Thanks in advance,
Simon
AppWidgetProvider:
package com.aquariumzoekenpro.android;
import java.io.InputStream;
import java.util.Random;
import java.util.Timer;
import java.util.TimerTask;
import com.aquariumzoekenpro.android.VissenDB.Vis;
import android.app.PendingIntent;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.widget.RemoteViews;
public class Widget extends AppWidgetProvider {
public static final String PREFS_NAME = "Vissen";
static SharedPreferences sharedPreferences;
PendingIntent pendingintent;
#Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds){
// final int N = appWidgetIds.length;
sharedPreferences = context.getSharedPreferences(PREFS_NAME, 0);
int rbitem = sharedPreferences.getInt("RBitem", 0);
// int appWidgetId = appWidgetIds[i];
ComponentName thisWidget = new ComponentName(context, Widget.class);
VissenDB db = new VissenDB();
int maxlength = db.lijst.size();
Random r = new Random();
int random = r.nextInt(maxlength - 0);
Vis v = db.lijst.get(random);
int imageresource = context.getResources().getIdentifier(v.afbeelding, "drawable", context.getPackageName());
InputStream is = context.getResources().openRawResource(imageresource);
Bitmap bm = BitmapFactory.decodeStream(is);
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget);
views.setImageViewBitmap(R.id.widget_imageview, bm);
Intent clickintent = new Intent(context, VissenBeschrijving.class);
clickintent.putExtra("list", rbitem);
String text = "";
if (rbitem == 0){
text = v.naam;
}else{
text = v.latijnseNaam;
}
clickintent.putExtra("selected", text);
clickintent.putExtra("Herkomst", "Encyclo");
clickintent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
pendingintent = PendingIntent.getActivity(context, 1, clickintent, 0);
views.setOnClickPendingIntent(R.id.widget_imageview, pendingintent);
appWidgetManager.updateAppWidget(thisWidget, views);
}
public Bitmap getResizedBitmap(Bitmap bm, int newHeight, int newWidth) {
int width = bm.getWidth();
int height = bm.getHeight();
float scaleWidth = ((float) newWidth) / width;
float scaleHeight = ((float) newHeight) / height;
// CREATE A MATRIX FOR THE MANIPULATION
Matrix matrix = new Matrix();
// RESIZE THE BIT MAP
matrix.postScale(scaleWidth, scaleHeight);
// RECREATE THE NEW BITMAP
Bitmap resizedBitmap = Bitmap.createBitmap(bm, 0, 0, width, height, matrix, false);
return resizedBitmap;
}
}
VissenBeschrijving (receiving activity):
i = this.getIntent();
VissenDB db = new VissenDB();
String h = i.getStringExtra("Herkomst");
if (i != null && h !=null){
text = i.getStringExtra("selected");
RBitem = i.getIntExtra("list", -1);
if (RBitem == 0){
//Nederlandse naam
for (VissenDB.Vis v : db.lijst) {
if (v.naam.equals(text)){
vis = v;
break;
}
}
}
else{
//Latijnse naam
for (VissenDB.Vis v : db.lijst) {
if (v.latijnseNaam.equals(text)){
vis = v;
break;
}
}
}
}
If I recall correctly this is because it will reuse the old intent if nothing has change in the content.
Try adding something unique to your click intent.
For example:
clickintent.setData(Uri.withAppendedPath(Uri.parse("myapp://widget/id/#togetituniqie" + appWidgetId), String.valueOf(appWidgetId)));
This is assuming you know the appWidgetId.
Otherwise you can use something else unique. Like UUID.randomUUID().toString()
For me it worked just adding the FLAG_UPDATE_CURRENT to the pending intent in the widget provider.
So, in this case it would be:
pendingintent = PendingIntent.getActivity(context, 1, clickintent, PendingIntent.FLAG_UPDATE_CURRENT);
This way it seems that the old pending intent used to open the activity gets updated with the new content sent from the widget provider, including the inner intent.
I had the same problem and I solved simply adding PendingIntent.FLAG_ONE_SHOT flag (if you want the intent is fired once) or PendingIntent.FLAG_UPDATE_CURRENT (if you want it will be executed on every click event):
Intent intent = new Intent(context, YourWidgetProvider.class);
intent.setAction(ACTION_NAME);
intent.putExtra("extraName", extraValue);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_ONE_SHOT);
remoteViews.setOnClickPendingIntent(R.id.view_id, pendingIntent);
Related
I'm trying to create a dynamic Icon for my notifications using a function that creates a Bitmap from a String.
When I started my project, I wanted to use API level 22, but I realized that public Notification.Builder setSmallIcon (Icon icon) was not available until API 23.
So I changed my MinSDKVersion, but i'm still getting that incompatible types error ...
package com.example.netmetah;
import android.app.IntentService;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.drawable.Icon;
import android.net.Uri;
import android.support.v4.app.NotificationCompat;
import android.widget.Toast;
import android.app.Notification.Builder;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
public class NetMonitorService extends IntentService {
public NetMonitorService() {
super("NetMeterListening");
}
#Override
protected void onHandleIntent(Intent workIntent) {
Context context = getApplicationContext();
CharSequence text = "Le service marche";
int duration = Toast.LENGTH_SHORT;
Toast toast = Toast.makeText(context, text, duration);
toast.show();
createNotification(createBitmapFromString("23","kb"));
}
private Bitmap createBitmapFromString(String speed, String units) {
Paint paint = new Paint();
paint.setAntiAlias(true);
paint.setTextSize(55);
paint.setTextAlign(Paint.Align.CENTER);
Paint unitsPaint = new Paint();
unitsPaint.setAntiAlias(true);
unitsPaint.setTextSize(40);
unitsPaint.setTextAlign(Paint.Align.CENTER);
Rect textBounds = new Rect();
paint.getTextBounds(speed, 0, speed.length(), textBounds);
Rect unitsTextBounds = new Rect();
unitsPaint.getTextBounds(units, 0, units.length(), unitsTextBounds);
int width = (textBounds.width() > unitsTextBounds.width()) ? textBounds.width() : unitsTextBounds.width();
Bitmap bitmap = Bitmap.createBitmap(width + 10, 90,
Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
canvas.drawText(speed, width / 2 + 5, 50, paint);
canvas.drawText(units, width / 2, 90, unitsPaint);
return bitmap;
}
public static long[] readProc() {
BufferedReader br;
String line;
String[] lines;
long rx = 0;
long tx = 0;
try {
br = new BufferedReader(new FileReader("/proc/net/dev"));
while ((line = br.readLine()) != null) {
if (line.contains("eth") || line.contains("wlan")) {
lines = line.trim().split("\\s+");
rx += Long.parseLong(lines[1]);
tx += Long.parseLong(lines[9]);
}
}
br.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
long[] bytes = {rx, tx};
return bytes;
}
private void createNotification(Bitmap icon) {
Intent notificationIntent = new Intent(Intent.ACTION_VIEW);
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
notificationIntent.setData(Uri.parse("http://www.google.ca"));
PendingIntent contentIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
Notification notification = new NotificationCompat.Builder(this, "fuck")
.setCategory(Notification.CATEGORY_PROMO)
.setSmallIcon(Icon.createWithBitmap(icon))
.setContentTitle("C'est quoi un titre")
.setContentText("C'est quoi un text")
.setAutoCancel(true)
.setVisibility(1) //Public
.addAction(android.R.drawable.ic_menu_view, "View details", contentIntent)
.setContentIntent(contentIntent)
.setPriority(Notification.PRIORITY_HIGH)
.setChannelId("fuck")
.setVibrate(new long[]{1000, 1000, 1000, 1000, 1000}).build();
NotificationManager notificationManager =
(NotificationManager) getSystemService(NOTIFICATION_SERVICE);
notificationManager.notify(123, notification);
}
}
You are using NotificationCompat.Builder. According to the documentation the setSmallIcon methods take a drawable resource ID.
It's easy to confuse this with the methods for Notification.Builder where one takes a drawable resource ID and the other one an Icon.
I want to get battery Current, and Voltage at an interval of 5 seconds.
But in my source, the Voltage and Current changes at an random interval.
such as 5 seconds, 10 seconds, 9 seconds, .......
I heard BroadcastReceiver requires a return value within 10 seconds.
I guess this is a cause, but I have no idea how to solve this problem.
package com.example.hubertlee.batterywearrate;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.BatteryManager;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
private TextView batteryInfo;
Long avgCurrent = null, currentNow = null;
int count = 0;
float power = 0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
BatteryManager mBatteryManager = (BatteryManager) getSystemService(Context.BATTERY_SERVICE);
batteryInfo = (TextView) findViewById(R.id.textViewBatteryInfo);
this.registerReceiver(this.batteryinfoReceiver, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
avgCurrent = mBatteryManager.getLongProperty(BatteryManager.BATTERY_PROPERTY_CURRENT_AVERAGE);
currentNow = mBatteryManager.getLongProperty(BatteryManager.BATTERY_PROPERTY_CURRENT_NOW);
}
}
private BroadcastReceiver batteryinfoReceiver = new BroadcastReceiver(){
public void onReceive(Context context, Intent intent){
int health = intent.getIntExtra(BatteryManager.EXTRA_HEALTH, 0);
int icon_small = intent.getIntExtra(BatteryManager.EXTRA_ICON_SMALL,0);
int level = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, 0);
int plugged = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, 0);
boolean present = intent.getExtras().getBoolean(BatteryManager.EXTRA_PRESENT);
int scale = intent.getIntExtra(BatteryManager.EXTRA_SCALE, 0);
int status = intent.getIntExtra(BatteryManager.EXTRA_STATUS, 0);
String technology = intent.getExtras().getString(BatteryManager.EXTRA_TECHNOLOGY);
float temp = intent.getIntExtra(BatteryManager.EXTRA_TEMPERATURE, 0);
float voltage = intent.getIntExtra(BatteryManager.EXTRA_VOLTAGE, 0);
batteryInfo.setText("Health: " + health + "\n" + "Icon small : "+icon_small+"\n" +
"Level : "+level+"\n"+"Present : "+present+"\n"+"Scale: "+
scale+"\n"+"Status :"+status+"\n"+ "Technology:"+technology+"\n"+
"Temperature :"+temp/10+"'C\n"+"Voltage:"+voltage/1000+"V\n"+"BATTERY_PROPERTY_CURRENT_AVERAGE = "
+ avgCurrent + "mAh"+"\n"+"BATTERY_PROPERTY_CURRENT_NOW = " + currentNow + "mAh"+"\n"+"count ="+count);
count++;
}
};
}
If you want to have a code run at fix interval, take a look at Alarm manager :
https://developer.android.com/reference/android/app/AlarmManager.html
Like Selvin said, the broadcast is called only when it change.
I have a clock widget that updates every minute. It renders a bitmap and replaces an imageview. This is to use a custom font in a widget. Below I showed the important pieces of my code. My problem is that the widget is there, but nothing shows up. I can still tap the widget to bring up the settings, so I know it's there. It's like the service update isn't working correctly in Kitkat but it does in Lollipop. Any suggestions?
public class DigitalClockWidget_2x1 extends AppWidgetProvider {
public RemoteViews mRemoteViews;
static String APP_SETTINGS = "8BitSettings";
#Override
public void onEnabled(Context context) {
super.onEnabled(context);
context.startService(new Intent(UpdateTimeService.UPDATE_TIME));
}
#Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
super.onUpdate(context, appWidgetManager, appWidgetIds);
mRemoteViews = new RemoteViews(context.getPackageName(), R.layout.widget);
Intent LaunchIntent = getLaunchIntent(context);
PendingIntent clickPendIntent = PendingIntent.getActivity(context, 0, LaunchIntent, PendingIntent.FLAG_UPDATE_CURRENT);
mRemoteViews.setOnClickPendingIntent(R.id.widget_root, clickPendIntent);
ComponentName componentName = new ComponentName(context.getPackageName(),DigitalClockWidget_2x1.class.getName());
appWidgetManager.updateAppWidget(componentName, mRemoteViews);
context.startService(new Intent(UpdateTimeService.UPDATE_TIME));
}
public static Intent getLaunchIntent(Context context){
SharedPreferences clockSettings = context.getSharedPreferences("ClockSettings", 0);
String launchString = clockSettings.getString("tappedAction", APP_SETTINGS);
if(launchString.compareTo(APP_SETTINGS) == 0){
return new Intent(context, SettingsPage.class);
}
return context.getPackageManager().getLaunchIntentForPackage(launchString);
}
public static final class UpdateTimeService extends Service {
static final String UPDATE_TIME = "org.penguinproductions.eight_bit_clock.action.UPDATE_TIME_2x1";
RemoteViews mRemoteViews;
private Calendar mCalendar;
private final static IntentFilter mIntentFilter = new IntentFilter();
int textColor = 0;
boolean tweentyfourHour = false;
SharedPreferences clockSettings;
String APP_SETTINGS = "8BitSettings";
static {
mIntentFilter.addAction(Intent.ACTION_TIME_TICK);
mIntentFilter.addAction(Intent.ACTION_TIME_CHANGED);
mIntentFilter.addAction(Intent.ACTION_TIMEZONE_CHANGED);
}
#Override
public void onCreate() {
super.onCreate();
mCalendar = Calendar.getInstance();
registerReceiver(mTimeChangedReceiver, mIntentFilter);
}
#Override
public void onDestroy() {
super.onDestroy();
unregisterReceiver(mTimeChangedReceiver);
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
super.onStartCommand(intent, flags, startId);
if (intent != null) {
if (UPDATE_TIME.equals(intent.getAction())) {
updateTime();
}
}
return START_STICKY;
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
private final BroadcastReceiver mTimeChangedReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
updateTime();
}
};
private void updateTime() {
mCalendar.setTimeInMillis(System.currentTimeMillis());
mRemoteViews = new RemoteViews(getPackageName(), R.layout.widget);
String date = DateFormat.format(getString(R.string.date_format), mCalendar).toString();
mRemoteViews.setImageViewBitmap(R.id.imageView_txt, buildUpdate(getTodaysTime(), mCalendar.get(Calendar.AM_PM), date));
ComponentName mComponentName = new ComponentName(this, DigitalClockWidget_2x1.class);
AppWidgetManager mAppWidgetManager = AppWidgetManager.getInstance(this);
mAppWidgetManager.updateAppWidget(mComponentName, mRemoteViews);
Intent LaunchIntent = getLaunchIntent(getBaseContext());
PendingIntent clickPendIntent = PendingIntent.getActivity(getBaseContext(), 0, LaunchIntent, PendingIntent.FLAG_UPDATE_CURRENT);
mRemoteViews.setOnClickPendingIntent(R.id.widget_root, clickPendIntent);
mAppWidgetManager = AppWidgetManager.getInstance(getBaseContext());
mAppWidgetManager.updateAppWidget(mComponentName, mRemoteViews);
}
}
EDIT:
The issue seems to have to do with the Bitmap rendering. I replaced the imageview with a textview and it worked. So the Bitmap isn't displaying in KitKat, but it does in Lollipop
public Bitmap buildUpdate(String time, int AMPM, String date) {
Log.v("Penguin", "Building time string:" + time);
clockSettings = this.getSharedPreferences("ClockSettings", 0);
boolean showDate = clockSettings.getBoolean("showDate", true);
boolean showampm = clockSettings.getBoolean("ampm", true);
boolean leading0 = clockSettings.getBoolean("leading0", true);
textColor = clockSettings.getInt("clockColor", Color.WHITE);
int dateColor = clockSettings.getInt("dateColor", Color.WHITE);
Bitmap myBitmap = Bitmap.createBitmap(2500, 1100, Bitmap.Config.ARGB_8888);
int fontSize = 425;
Canvas myCanvas = new Canvas(myBitmap);
Paint paint = new Paint();
Typeface clock = Typeface.createFromAsset(this.getAssets(), "fonts/PressStart2P.ttf");
paint.setAntiAlias(true);
paint.setSubpixelText(true);
paint.setTypeface(clock);
paint.setStyle(Paint.Style.FILL);
paint.setColor(textColor);
paint.setTextSize(fontSize);
paint.setTextAlign(Paint.Align.CENTER);
myCanvas.drawText(time, myBitmap.getWidth() / 2, fontSize+200, paint);
paint.setTextSize(100);
if(showampm) {
// alert("AMPM");
String ampm = "AM";
if (AMPM == 1) ampm = "PM";
myCanvas.drawText(ampm, (myBitmap.getWidth() / 2) + ((time.length() * fontSize) / 2) + 100, 300, paint);
}
paint.setTextSize(125);
if(showDate) {
paint.setColor(dateColor);
myCanvas.drawText(date, myBitmap.getWidth() / 2, (myBitmap.getHeight() / 2 + 400), paint);
}
return myBitmap;
}
So the issue was that the size limit for my older phone running KitKat only allows for texture sizes no bigger than 2048x2048 pixels. My bitmap was 2500x1100, so scaling it down has fixed the issue
I am going to make custom notification bar. But not great.
I would like to create an Large icon.
remoteViews = new RemoteViews(getPackageName(), R.layout.widget_main);
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this)
.setContentTitle("Title")
.setTicker("Ticker")
.setSmallIcon(R.mipmap.howlong)
.setLargeIcon(BitmapFactory.decodeResource(getResources(), R.mipmap.howlong))//I dot understand why entering this icon.
.setContent(remoteViews).setOngoing(true);
This my code.
https://www.dropbox.com/s/njywqp5s5swtfdd/img.jpg?dl=0
This my notification state.
How can I have put the Large icon?
------------------------------------add code-------------------------------
package com.example.namsoo.mynotificationpractice5;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.IBinder;
import android.support.v4.app.NotificationCompat;
import android.widget.RemoteViews;
import android.widget.Toast;
/**
* Created by namsoo on 2015-07-22.
*/
/*
Add code for manifest
<service android:name=".WidgetService"
android:enabled="true"
android:exported="true" >
</service>
*/
/*
Add code for MainActivity.onCreate
Intent widgetIntent = new Intent(this, WidgetService.class);
startService(widgetIntent);
*/
public class WidgetService extends Service {
RemoteViews remoteViews;
NotificationManager notificationManager;
int NOTIFICATION_ID = 111;
int INITIAL_VALUE = 0;//초기값
int FUNCTION_ON =1;//ON
int FUNCTION_OFF =2;//OFF
int functionFlag = 0;//0 = 초기 1 = ON 2 = OFF
#Override
public void onCreate() {
Toast.makeText(getApplicationContext(), "Start Widget Service", Toast.LENGTH_LONG).show();
startWidget();
super.onCreate();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
remoteViews = new RemoteViews(getPackageName(), R.layout.widget_main);
NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
String btn = intent.getStringExtra("btn");
if (btn != null)
{
if (btn.equals("state"))
{
//function code or Value redirects.
startWidget();
Toast.makeText(getApplicationContext(), "btn : " + btn + startId + " " + flags, Toast.LENGTH_LONG).show();
}
else if (btn.equals("exit"))
{
Toast.makeText(getApplicationContext(), "btn : " + btn + startId + " " + flags, Toast.LENGTH_LONG).show();
notificationManager.cancelAll();
stopService(intent);
System.exit(1);
}
else
{
Toast.makeText(getApplicationContext(), "not null btn : " + btn, Toast.LENGTH_LONG).show();
}
}
else
{
Toast.makeText(getApplicationContext(), " null btn", Toast.LENGTH_LONG).show();
}
return super.onStartCommand(intent, flags, startId);
}//서비스 실행
public void startWidget() {
if (functionFlag != INITIAL_VALUE) {
remoteViews.removeAllViews(R.id.widgetLayout);
}//노피티케이션 뷰 삭제(처음이 아닐때만 실행)
remoteViews = new RemoteViews(getPackageName(), R.layout.widget_main);//뷰 추가
setWidgetButtonListeners();//버튼이벤트 추가
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this)
.setSmallIcon(R.mipmap.ic_launcher)
.setContent(remoteViews).setOngoing(true);
// Creates an explicit intent for an Activity in your app
Intent resultIntent = new Intent(this, MainActivity.class);
resultIntent.addFlags(resultIntent.FLAG_ACTIVITY_NEW_TASK | resultIntent.FLAG_ACTIVITY_SINGLE_TOP);//화면이 없는 상태에서 만들어주는 플래그 || 화면이 있으면 화면을 재사용하세요.
PendingIntent resultPendingIntent = PendingIntent.getActivity(getApplicationContext(), 0, resultIntent, 0);
// start the activity when the user clicks the notification text
mBuilder.setContentIntent(resultPendingIntent).setAutoCancel(false);
notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
// pass the Notification object to the system
notificationManager.notify(NOTIFICATION_ID, mBuilder.build());
}
public void setWidgetButtonListeners() {
if (functionFlag == INITIAL_VALUE) {
remoteViews.setImageViewResource(R.id.btnState, android.R.drawable.ic_media_pause);
remoteViews.setTextViewText(R.id.tv, "On~~");
functionFlag = FUNCTION_ON;
} else if (functionFlag == FUNCTION_ON)//On 일 때
{
remoteViews.setImageViewResource(R.id.btnState, android.R.drawable.ic_media_play);
remoteViews.setTextViewText(R.id.tv, "Off~~");
functionFlag = FUNCTION_OFF;
} else if (functionFlag == FUNCTION_OFF)//Off 일 때
{
remoteViews.setImageViewResource(R.id.btnState, android.R.drawable.ic_media_pause);
remoteViews.setTextViewText(R.id.tv, "On");
functionFlag = FUNCTION_ON;
}//버튼과 텍스트의 값 변경
Intent intentBtnState = new Intent(getApplicationContext(), this.getClass());
intentBtnState.putExtra("btn", "state");
PendingIntent piState = PendingIntent.getService(getApplicationContext(), R.id.btnState, intentBtnState, PendingIntent.FLAG_UPDATE_CURRENT);
remoteViews.setOnClickPendingIntent(R.id.btnState, piState);
Intent intentBtnExit = new Intent(getApplicationContext(), this.getClass());
intentBtnExit.putExtra("btn", "exit");
PendingIntent piExit = PendingIntent.getService(getApplicationContext(), R.id.btnExit, intentBtnExit, PendingIntent.FLAG_UPDATE_CURRENT);
remoteViews.setOnClickPendingIntent(R.id.btnExit, piExit);
//이벤트 추가
}
#Override
public void onDestroy() {
Toast.makeText(getApplicationContext(), "Destroy", Toast.LENGTH_LONG).show();
super.onDestroy();
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
}
private Bitmap getCircleBitmap(Bitmap bitmap) {
final Bitmap output = Bitmap.createBitmap(bitmap.getWidth(),
bitmap.getHeight(), Bitmap.Config.ARGB_8888);
final Canvas canvas = new Canvas(output);
final int color = Color.RED;
final Paint paint = new Paint();
final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());
final RectF rectF = new RectF(rect);
paint.setAntiAlias(true);
canvas.drawARGB(0, 0, 0, 0);
paint.setColor(color);
canvas.drawOval(rectF, paint);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
canvas.drawBitmap(bitmap, rect, rect, paint);
bitmap.recycle();
return output;
}
How would I go about navigating to a specific page with the muPDF library? Or is there a way to make the library not remember which page I was last on in that pdf?
Uri uri = Uri.parse(path);
Intent intent = new Intent(MainActivity.getContext(), MuPDFActivity.class)
intent.setAction(Intent.ACTION_VIEW);
intent.setData(uri);
c.startActivity(intent);
//c is context
This is how i'm currently opening pdfs.
You can add page index in Bundle into your intent, load that index in MuPDFActivity thereafter and call mDocView.setDisplayedViewIndex(your_index_from_bundle); That should do the job.
Something like that:
Uri uri = Uri.parse(path);
Intent intent = new Intent(MainActivity.getContext(), MuPDFActivity.class)
intent.setAction(Intent.ACTION_VIEW);
intent.setData(uri);
Bundle extras = intent.getExtras();
extras.putInt("key_page_index", 10);
c.startActivity(intent);
Then edit onCreate in MuPDFActivity, add this code at the end of the onCreate:
Intent intent = getIntent();
if(intent!=null){
Bundle extras = intent.getExtras();
if(extras!=null){
int index = extras.getInt("key_page_index");
mDocView.setDisplayedViewIndex(index);
}
}
package com.artifex.mupdf;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Point;
import android.util.Log;
public class MuPDFPageView extends PageView {
private final MuPDFCore mCore;
public MuPDFPageView(Context c, MuPDFCore core, Point parentSize) {
super(c, parentSize);
mCore = core;
}
public String hitLinkPage(float x, float y) {
// Since link highlighting was implemented, the super class
// PageView has had sufficient information to be able to
// perform this method directly. Making that change would
// make MuPDFCore.hitLinkPage superfluous.
float scale = mSourceScale * getWidth() / mSize.x ;
float docRelX = (x - getLeft()) / scale;
float docRelY = (y - getTop()) / scale;
Log.d("Page Number", "hitLinkPage with page = " + mCore.hitLinkPage(mPageNumber, docRelX, docRelY));
return mCore.hitLinkPage(mPageNumber, docRelX, docRelY);
}
#Override
protected void drawPage(Bitmap bm, int sizeX, int sizeY, int patchX,
int patchY, int patchWidth, int patchHeight) {
mCore.drawPage(mPageNumber, bm, sizeX, sizeY, patchX, patchY,
patchWidth, patchHeight);
}
#Override
protected LinkInfo[] getLinkInfo() {
return mCore.getPageLinks(mPageNumber);
}
}